数据结构总复习(1)

  根据数据结构书上来复习(提醒一下自己,学会自己总结,而不是去看很多试题,如果掌握原理了,就不用担心任何出题形式了。一定要注重基础)

   一:线性表

   1,线性表的两种表示和实现

    1)顺序表示和实现

       顺序表示是用一组地址连续的存储单元依次存储线性表的数据元素。顺序存储结构一般用数组来描述,由于线性表的长度可变,所以用动态分配的一维数组

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define LIST_INIT_SIZE 100
 4 #define LISTAdd 10
 5 typedef struct{
 6       char *elem;//暂且用char
 7       int length;//当期长度
 8       int listsize;//当前分配的存储容量
 9 }SqList;
10 void InitList(SqList &L)
11  {
12      //初始化
13      L.elem=(char *)malloc(LIST_INIT_SIZE*sizeof(char));
14      if(!L.elem)
15        exit(0);//正常退出,0表示正常退出,其他表示非正常退出
16      L.length=0;
17      L.listsize=LIST_INIT_SIZE;
18 }
19     
20 
21 //线性表的插入,在第i个元素之前插入
22 void ListInsert(SqList &L,int i, char e)
23 {
24   //if((i<1)||(i>L.length+1))
25           // return 0;
26   if(L.length>=L.listsize)
27   {
28       char *newbase=(char *)realloc(L.elem,(L.listsize+LISTAdd)*sizeof(char));
29       if(!newbase)
30           exit(0);
31         //return 0在一个函数中是正常的返回过程,它会使得程序返回到函数被调用处,回复之前的执行流程,
32        //而exit 一般是在任意位置和使用的,执行到exit 0时,
33       //整个进程就over了(这也是为什么在多线程程序中不要随意使用exit的原因),用来使程序退出运行,一般用来处理(不可挽回的)错误状态。
34       //2. return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。
35       //3. return是函数的退出(返回);exit是进程的退出。
36       // 4. return是C语言提供的,exit是操作系统提供的(或者函数库中给出的)。
37       //5. return用于结束一个函数的执行,将函数的执行信息传出个其他调用函数使用;
38       //exit函数是退出应用程序,删除进程使用的内存空间,并将应用程序的一个状态返回给OS,这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关,一般是 0 为正常退出,非0 为非正常退出。
39       L.elem=newbase;
40       L.listsize+=LISTAdd;
41   }
42   char *q=&(L.elem[i-1]);
43   char *p;
44   for(p=&(L.elem[L.length-1]);p>=q;--p)
45       *(p+1)=*p;//插入位置及之后的元素往后移
46   *q=e;
47   L.length++;
48 }
49 //从线性表中删除第i个元素,并用e返回其值
50 void ListDelete(SqList &L,int i,char &e)
51 {
52     //if((i<1)||(i>L.length))
53         //return 0;
54     char *p=&(L.elem[i-1]);
55     e=*p;
56     char *q=&(L.elem[L.length-1]);//表尾元素的位置
57     for(++p;p<=q;++p)
58         *(p-1)=*p;//被删除元素之后的元素左移
59     L.length--;
60 }
61 int main(void)
62 {
63     SqList L;
64     int k=0;
65     char e;
66     InitList(L);
67     printf("请输入要插入线性表中的个数:");
68     scanf("%d",&k);
69     for(int j=1;j<=k;j++)
70     {
71        char c;
72        printf("输入第%d个元素\n",j-1);
73        scanf(" %c",&c);//scanf("%c",&c) 与 scanf(" %c",&c),后者只是在%前多了个空格,似乎没有什么区别,但使用起来区别是很大的。
74                        //scanf()作单字符输入时规定只接收一个字符,但它却把回车符也作为字符对待的。
75                        //这就造成程序中只有一个输入字符的scanf()语句时,问题还不大,但如果后面还跟着第二个scanf()字符输入语句,这个scanf()就把前面输入的驾车符当作输入字符了。这就在输入逻辑上造成了混乱,达不到人们预期的愿望。有了这个空格,因为scanf()是跳过空格读字符的,就回避了这个问题。实践证明,这个空格放在%c后面也不能达到目的。应当说,这也是比较巧妙的应用!
76        ListInsert(L,j,c);
77     }
78     //ListInsert(L,1,'a');
79     //ListInsert(L,2,'v');
80     //ListInsert(L,3,'q');
81     //ListInsert(L,4,'t');
82     printf("你想删除第几个元素呢?\n");
83     scanf("%d",&k);
84     ListDelete(L,k,e);//
85     printf("线性表中的元素的值是:\n");
86     for(int i=0;i<L.length;i++)
87     printf("%c\n",L.elem[i]);
88     printf("你删除的元素是:%c\n",e);
89     return 0;
90 }
View Code

 

运行结果:

 2)链表表示和实现

  链式存储结构:用一组任意的存储单元存储线性表的数据元素(这组存储单元可以使连续的也可以是不连续的),n个结点链结成一个链表,即为线性表的链式存储结构。

两者的区别:线性表的顺序存储结构中,逻辑上相邻的两个元素在物理位置上紧邻,每个元素的存储位置都可从线性表的起始位置计算可得。在单链表中,任何两个元素之间没有固定的关系,但是每个元素的存储位置都包含在其直接前驱结点的信息中。前者是随机存取,后者是非随机存取。

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 typedef struct LNode{
 4       char data;//暂且用char
 5       struct LNode *next;
 6 }LNode,*LinkList;
 7 
 8 //带头结点的单链表线性表L中第i个位置之后插入元素e
 9 void ListInsert_L(LinkList &L,int i, char e)
10 {
11    LNode *p,*s;
12    p=L;
13    int j=0;
14    while(p&&j<i-1)
15    {
16        p=p->next;
17        ++j;//找到第i-1个结点
18    }
19    s=(LinkList)malloc(sizeof(LNode));//生成新结点
20    s->data=e;
21    s->next=p->next;//插入L中
22    p->next=s;
23 }
24 //带头结点的单链表线性表L中删除第i个位置的元素,并由e返回其值
25 void ListDelete(LinkList &L,int i,char &e)
26 {
27     LNode *p,*q;
28     p=L;
29     int j=0;
30     while(p->next&&j<i-1)
31     {
32       p=p->next;
33       j++;
34     }
35     q=p->next;//删除p后面的元素
36     p->next=q->next;
37     e=q->data;
38     free(q);
39 }
40 int main(void)
41 {
42     LinkList L,PrintL;
43     int k;
44     char e;
45     L=(LinkList)malloc(sizeof(LNode));//生成头结点
46     L->next=NULL;
47     printf("要输入链表中的数据的个数为:\n");
48     scanf("%d",&k);
49     for(int i=1;i<=k;i++)
50     {
51         printf("输入第%d个元素\n",i);
52         char c;
53         scanf(" %c",&c);
54         ListInsert_L(L,i,c);
55     }
56     printf("你要删除的元素的位置是:\n");
57     scanf("%d",&k);
58     ListDelete(L,k,e);
59     printf("链表中的数据是:\n");
60     PrintL=L->next;
61     while(PrintL)
62     {
63       printf("%c\n",PrintL->data);
64       PrintL=PrintL->next;
65     }
66     printf("你删除的元素是:%c\n",e);
67     return 0;
68 }
View Code

 二:栈和队列

栈和队列也是线性表,其特殊性在于栈和队列的基本操作时线性表操作的子集,它们是操作受限的线性表,可称为限定性的数据结构。

 1)栈的基本操作:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #define stack_init_size 100//预编译
 4 #define stackAdd 10
 5 /*
 6 http://blog.sina.com.cn/s/blog_861912cd0101hzrb.html 预编译详解
 7 */
 8 typedef struct {
 9       char *base;//暂且用char,在栈构造之前和销毁之后,base的值为NULL
10       char *top;//栈顶指针
11       int stacksize;//当前已分配的存储空间
12 }SqStack;
13 
14 void InitStack(SqStack &s)
15 {
16     s.base=(char *)malloc(stack_init_size * sizeof(char));
17     if(!s.base)
18         exit(0);
19     s.top=s.base;
20     s.stacksize=stack_init_size;
21 }
22 void Push(SqStack &s,char e)
23 {
24     if(s.top-s.base>=s.stacksize)
25     {
26         s.base=(char *)realloc(s.base,(s.stacksize+stackAdd)*sizeof(char));
27         if(!s.base)
28             exit(0);
29         s.top=s.base+s.stacksize;
30         s.stacksize+=stackAdd;
31     }
32     *s.top++ =e;
33 }
34 
35 void Pop(SqStack &s,char &e)
36 {
37     if(s.top==s.base)
38         printf("栈中无元素!");
39     e=* --s.top;
40 }
41 
42 
43 int main(void)
44 {
45     SqStack s;
46     char e;
47     InitStack(s);
48     Push(s,'a');
49     Pop(s,e);
50     printf("%c\n",e);
51     return 0;
52 }
View Code

 2)队列的基本操作:

 

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 typedef struct QNode{
 4   char data;
 5   struct QNode *next;
 6 }QNode,*QueuePtr;
 7 typedef struct{
 8       QueuePtr front;//队头指针
 9       QueuePtr rear;//队尾指针
10 }LinkQueue;
11 
12 void InitQueue(LinkQueue &Q)
13 {
14     Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
15     Q.front->next=NULL;
16     //Q.rear->next=NULL;
17 }
18 void EnQueue(LinkQueue &Q,char e)
19 {
20     QueuePtr p;
21     p=(QueuePtr)malloc(sizeof(QNode));
22     if(!p)
23         exit(0);
24     p->data=e;
25     p->next=NULL;
26     Q.rear->next=p;
27     Q.rear=p;//队尾指向新进来的元素
28 }
29 void DeQueue(LinkQueue &Q,char &e)
30 {
31   //若队列不空,则删除Q的队头元素,用e返回其值
32     if(Q.rear==Q.front)
33         printf("队列为空!");
34       QueuePtr p;
35       p=Q.front->next;
36       e=p->data;
37       Q.front->next=p->next;
38       if(Q.rear==p)
39           Q.front=Q.rear;//删除队列中最后一个元素
40       free(p);
41 }
42 int main(void)
43 {
44     LinkQueue q;
45     char e;
46     InitQueue(q);
47     EnQueue(q,'a');
48     DeQueue(q,e);
49     printf("%c\n",e);
50     return 0;
51 }
View Code

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    

 

posted @ 2013-09-29 19:44  wj704  阅读(256)  评论(0编辑  收藏  举报