这学期初学数据结构,同时学C语言。由于修的二专,没什么伙伴可以一块讨论。困惑还是很多的,希望自己可以坚持下来吧。
刚开始学的是线性表。线性表又可以分为顺序表和链表,两者的区别在于存储结构不同。
顺序表的存储特点是 依次存储,地址连续。因为地址连续,所以可以随机存取。
写一个构造体,命名为SqList。
1 typedef structView Code
2 {
3 int data[Max_Length];
4 int length;
5 }SqList;
而链表的特点是 任意存放,存储单元可以是不连续的,通过指针将一个个元素连接起来。指针真是个神奇的东西。。
写一个链表构造体,命名为Linknode。
1 typedef struct Linknode{View Code
2 int data;
3 struct Linknode *next;
4 }Linknode,*Linklist;
显然,两者各有优点和缺点。优缺点互补。
顺序表的缺点是插入删除繁琐,导致这一致命问题的原因在于依次存放,如果想插入一个元素,那势必要将表中该位置以后的元素后移一位。如果想删除一个元素,势必要将表中该位置以后的元素前移一位。
顺序表插入
1 int List_Insert(SqList &L,int i,int e)View Code
2 {
3 int *p;
4 int *q;
5 //插入位置的前一位置
6 q = &(L.data[i - 1]);
7 //插入位置的后面的元素后移一位
8 for(p = &L.data[L.length - 1];p >= q;--p)
9 {
10 *(p + 1) = *p;
11 }
12 *q = e;
13 ++L.length;
14 return 0;
15 }
顺序表删除
1 //按元素删除View Code
2 int List_Delete_Elem(SqList &L,ElemType e)
3 {
4 int j;
5 //找到第一个所给元素
6 for (j = 0;j <= L.length - 1;j++)
7 {
8 if(L.data[j] == e) break;
9 }
10 if (j >= L.length)
11 {
12 return 0;
13 }
14 int *p = &(L.data[j]);
15 int *q = &L.data[0] + L.length -1;
16 //删除元素的后面元素前移
17 for (++p;p <= q;++p)
18 {
19 *(p - 1) = *p;
20 }
21 --L.length;
22 return 1;
23 }
24
25 // 按照位置,删除表中指定位置元素
26 Status List_Delete_Pos(SqList &L, int i)
27 {
28 if (i < 1 || i > L.length)
29 {
30 return 0;
31 }
32 int *p = &(L.data[i-1]);
33 int *q = &L.data[0] + L.length -1;
34 for (++p; p <= q; ++p)
35 {
36 *(p - 1) = *p;
37 }
38 --L.length;
39 return 1;
40 }
依次存储 的问题在于,元素之间相互影响,这就好比一支军队,排列整齐的一列队伍,一个人的变动会影响全局。
那么,如果不是依次存储呢?链表的优势在于任意存储,形状不固定。人们将它视为一个链条,相互之间的连接依靠指针。我们老师的比喻比较形象,指针是开锁的钥匙,锁在另一个位置。一个元素包括下一个元素的地址,因此我们进入这个元素的房间,便可以找到这个房间存放的另一个房间的地址,从而也就找到了下一个房间。这里,一个房间由两种基本类型组成,一个是数据,一个是指针。
那么,链表如何插入和删除元素呢?我们想加入一个元素P,那个先找到加入的位置的前一个元素A,先使得P存放的地址是A存放的地址,然后使得A存放的地址是P的地址。同理,删除一个元素P,先找到加入的位置的前一个元素A,使得A存放的地址是P的存放的地址。
1 int List_Insert(Linklist &L,int i,int e)View Code
2 {
3 Linklist p,s;
4 p = L;
5 int j = 0;
6 while(p->next && j < i - 1)
7 {
8 p = p ->next;
9 ++j;
10 }
11 if(!p || j > i - 1) return ERROR;
12 s = (Linklist)malloc(sizeof(Lnode));
13 s->data = e;
14 s->next = p->next;
15 p->next = s;
16 return 1;
17 }
1 int List_Delete_Pos(Linklist &L,int i)View Code
2 {
3 Linklist p,q;
4 p = L;
5 int j,e ;
6 j = 0;
7 while(p->next && j < i - 1)
8 {
9 p = p->next;
10 j++;
11 }
12 if(!(p->next) || j > i - 1) return ERROR;
13 q = p->next;
14 p->next = q->next;
15 e = q->data;
16 free(q);
17 return 1;
18 }
19
20 int List_Delete_Elem(Linklist &L,int m)
21 {
22 Linklist p,q;
23 p = L;
24 int j,e ;
25 j = 0;
26 while(p->next && p->next->data != m)
27 {
28 p = p->next;
29 }
30 if(!(p->next)) return ERROR;
31 q = p->next;
32 p->next = q->next;
33 e = q->data;
34 free(q);
35 return 1;
36 }