1 1//代码来自浙大数据结构的讲义 2 #include <stdio.h> 3 #include <stdlib.h> 4 5 typedef struct Node 6 { 7 ElementType Data; 8 struct Node *Next; 9 }List; 10 List L, *ptrL; 11 12 ////////////////////////////////////////////////////////////////////////// 13 //主要操作 14 ////////////////////////////////////////////////////////////////////////// 15 16 //1.求表长 17 int Length(List *ptrL) 18 { 19 List *p = ptrL; //ptrL指向开始的,不要修改它,所以用p来代替 20 int j = 0; 21 while (p) 22 { 23 p = p->Next; //这里看做p指向p->Next. 24 j++; 25 } 26 return j; 27 } 28 29 //2.查找 30 //(1)按序号查找:FindKth (顺序表中直接a[k-1]找到) 31 List *FindKth(int K, List *ptrL) //找到之后要留下return回来. 32 { 33 List *p = ptrL; 34 int i = 1; 35 while (p != NULL && i < K) 36 { 37 p = p->Next; 38 i++; 39 } 40 41 //这个if...else块不能改成直接return p:因为前面没有对K的判断,倘若K这里<1,则会返回表头. 42 if (i == K) 43 { 44 return p; 45 } 46 else 47 return NULL; 48 } 49 //(2)按值查找 50 List *Find(ElementType X, List *ptrL) 51 { 52 List *p = ptrL; 53 while (p != NULL && p->Data != X) 54 { 55 p = p->Next; 56 } 57 58 //这个if...else块可以直接转化为return p,因为while结束只有两种情况:p==null或者p找到了X.而且下面这个实际上就是画蛇添足了.对比前面的. 59 // if (p == NULL) 60 // { 61 // return NULL; 62 // } 63 // else 64 // return p; 65 return p; 66 } 67 68 //3.插入(在第i-1(1 <= i <= n+1)个结点后插入一个值为X的新结点) 69 //(1)先构造新结点,用s指向 70 //(2)再找到链表的i-1个结点,用p指向 71 //(3)修改指针,插入结点(p之后插入s) 72 73 List *Insert(ElementType X, int i, List *ptrL) //链式插入和删除操作返回值都是List *,且返回地址是表头的地址,是因为表头的地址会改变,比如新结点插入到表头,则之前的表头地址就跑到后面了. 74 { //而顺序表的表头地址就是那个地方,插入和删除不会影响,所以不用返回表头地址,返回值为void. 75 //另外:链式是查到结点后面,而顺序表示插在某个位置处.(详见讲义) 76 List *p, *s; 77 if (i==1) 78 { 79 s = (List *)malloc(sizeof(List)); 80 s->Data = X; 81 s->Next = ptrL; 82 return s; 83 } 84 p = FindKth(i - 1, ptrL); 85 if (p==NULL) 86 { 87 printf("参数i错误"); 88 } 89 else 90 { 91 s = (List *)malloc(sizeof(List)); 92 s->Data = X; 93 s->Next = p->Next; //不论是顺序还是链式,插入都是先管后面的(s->Next). 94 p->Next = s; //貌似,两者接上了,(s->Next = p->Next;p->Next = s;)实际上=是从右到左,根本没有接上. 95 return ptrL; 96 } 97 } 98 99 //4.删除(第i个位置(1 <= i <= n+1))) //为啥都没有删除某个元素啊(因为完全可以先找到它的位置,然后再去删除对应的位置) 100 List *Delete(int i, List *ptrL) 101 { 102 List *p, *s; 103 if (i == 1) 104 { 105 s = ptrL; 106 if (ptrL != NULL) //删除之前都要看看是不是为空. 操作之前先敲门(比如插入前,判断顺序表示不是满了,链表不存在满一说;删除前是不是空表,或者空链.) 107 { 108 ptrL = ptrL->Next; 109 } 110 else 111 return NULL; //如果链表为空,则直接返回. 112 free(s); 113 return ptrL; 114 } 115 p = FindKth(i - 1, ptrL); 116 if (p==NULL) 117 { 118 printf("参数i错误"); 119 } 120 else 121 { 122 s = p->Next; 123 p->Next = s->Next; 124 free(s); 125 return ptrL; 126 } 127 }