标签:
基本操作: 创建、查找、删除、插入
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<time.h> 4 5 #define OK 1 6 #define ERROR 0 7 #define TRUE 1 8 #define FALSE 0 9 #define ElementType int 10 11 typedef int Status; 12 typedef struct Node{ 13 ElementType Element; 14 struct Node *Next; 15 }Node; 16 typedef struct Node LinkList; 17 18 int InitList(LinkList *L) 19 { 20 L = (LinkList*)malloc(sizeof(Node)); //给指针分配空间 21 if(!(L)) 22 { 23 return ERROR; 24 } 25 L ->Next = NULL; // 26 return OK; 27 } 28 int ListLength(LinkList *head) 29 { 30 int length =0; 31 LinkList *p = head -> Next; 32 while(p != NULL) 33 { 34 length ++; 35 p = p->Next; 36 } 37 return length; 38 } 39 /*将元素插入到链表的第i个位置*/ 40 int InsertList(ElementType e,int i,LinkList *head) 41 { 42 LinkList *p = head ; 43 LinkList *temp; 44 if(i <= ListLength(head)) 45 { 46 while(i-1) 47 { 48 p = p->Next; 49 i--; 50 } //p是第i个结点的前一个结点 51 temp = (Node*)malloc(sizeof(LinkList)); 52 temp ->Element = e; 53 temp ->Next = p ->Next; 54 p -> Next = temp; 55 return OK; 56 } 57 else 58 { 59 return ERROR; 60 } 61 } 62 //将列表中的元素输出 63 void ListTraverse(LinkList *head) 64 { 65 LinkList *p = head -> Next; 66 while(p) 67 { 68 printf("%d ",p->Element); 69 p = p ->Next; 70 } 71 } 72 /* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */ 73 /* 操作结果:删除list的第i个数据元素,并用e返回其值,list的长度减1 */ 74 Status ListDelete(LinkList *head,int i,ElementType *e) 75 { 76 LinkList *p = head; 77 LinkList *temp; 78 if(i <= ListLength(head)) 79 { 80 while(i-1) 81 { 82 p = p -> Next; 83 i--; 84 } //p指向被删除结点的前一项 85 temp = p -> Next; 86 p -> Next = temp ->Next; 87 free(temp); 88 return OK; 89 } 90 else 91 return ERROR; 92 } 93 /*得到head中第i个元素的值*/ 94 ElementType GetElement(LinkList *head,int i) 95 { 96 LinkList *p = head; 97 // LinkList *temp; 98 if(i <= ListLength(head)) 99 { 100 while(i) 101 { 102 p = p -> Next; 103 i--; 104 } //p指向第i个结点 105 106 return p ->Element;; 107 } 108 else 109 return ERROR; 110 } 111 112 /* 113 声明一个结点temp和计数器变量i 114 初始化一空链表L 115 循环 116 初始化temp 117 temp插入到头结点和前一新结点之间 118 *********************************************************** 119 随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */ 120 void CreateListHead(LinkList *L, int n) 121 { 122 LinkList *temp; 123 int i; 124 srand(time(0)); 125 L = (LinkList*)malloc(sizeof(Node)); 126 for(i = 0;i < n; i++) 127 { 128 temp = (LinkList*)malloc(sizeof(Node)); 129 temp -> Element = rand() %100 +1; 130 temp -> Next = L ->Next; 131 L -> Next = temp; 132 } 133 134 } 135 //尾插法 136 void CreateListTail(LinkList *L,int n) 137 { 138 LinkList *temp,*p; 139 int i; 140 141 L = (LinkList*)malloc(sizeof(Node)); 142 p = L; 143 for(i =0;i < n; i++) 144 { 145 temp = (LinkList*)malloc(sizeof(Node)); 146 temp -> Element = rand()%100 +1; 147 p -> Next= temp; 148 p = temp; 149 150 } 151 p -> Next = NULL; 152 153 } 154 /* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */ 155 Status ClearList(LinkList *L) 156 { 157 LinkList *q,*p; 158 p = L-> Next; 159 while(p != NULL) 160 { 161 q = p -> Next; 162 free(p); 163 p = q; 164 } 165 L -> Next = NULL; 166 return OK; 167 } 168 /*********************************** 169 **************列表反转的3种方法**** 170 *********************************** 171 ListReverse1 172 173 */ 174 LinkList* ListReverse1 (LinkList *L) 175 { 176 LinkList *current; 177 LinkList *p; 178 179 current = L -> Next; 180 while(current -> Next != NULL) 181 { 182 p = current -> Next; 183 current -> Next = p -> Next ; 184 p -> Next = L -> Next; 185 L -> Next = p; 186 } 187 return L; 188 } 189 LinkList* LisReverse2(LinkList *L) 190 { 191 LinkList *current ,*pnext,*prev; 192 if(L == NULL || L -> Next == NULL) 193 return L; 194 current = L->Next; 195 pnext = current -> Next; 196 current -> Next = NULL; 197 while(pnext) 198 { 199 prev = pnext -> Next; 200 pnext -> Next = current; 201 current = pnext; 202 pnext = prev; 203 } 204 L -> Next = current; 205 return L; 206 } 207 int HasLoop (LinkList *L) 208 { 209 LinkList *q,*p; 210 int step1 = 0; 211 212 213 q = L -> Next; 214 while(q) 215 { 216 step1++; 217 int step2 = 0; 218 p = L -> Next; 219 while(p) 220 { 221 step2++; 222 if(p == q) 223 { 224 if(step1 == step2) 225 break; 226 else 227 return 1; 228 } 229 p = p -> Next; 230 } 231 q = q -> Next; 232 } 233 return 0; 234 } 235 void CreateLoop(LinkList *L ,int num) 236 { 237 int i;//count 238 LinkList *current; 239 LinkList *p = L -> Next; 240 for(i = 0;i < num; i++) 241 { 242 if(p == NULL) 243 { 244 return 0; 245 } 246 p = p -> Next; 247 } 248 current = p; 249 while(p->Next) 250 { 251 p = p -> Next; 252 } 253 p -> Next = current; 254 return 1; 255 } 256 int main() 257 { 258 LinkList *l; 259 InitList(l); 260 ListLength(l); 261 return 0; 262 }
*求单链表的倒数第k个数,声明2个指针,一个指针先走k步,然后两个指针一起走。当第一个指针next == NULL时,di二个指针就是倒数第k个结点的值。
*用标尺法求未知长度单链表的中间节点
**声明2个指针,search,mid。search指针的移动速度是mid指针的2倍,当search指针到达链表结尾时。mid指针到达链表中间。
*使用2个快慢指针可以判断。如果有环,它们在某点相遇。
int HasLoop (LinkList *L) { LinkList *q,*p; q =p =L -> Next; int stepq//length of q int stepp //length of p while(p != NULL && q != NULL && q -> Next != NULL) { p = p -> Next; if(q -> Next != NULL) q = q -> Next -> Next; if(q = p) return 1 } return 0; }
*第二种方法 和嵌套循环类似 设2个指针q、p,p走一步,q每次从头走到结束。如果有环,结点相同时步数不相等。
int HasLoop (LinkList *L) { LinkList *q,*p; int step1 = 0; q = L -> Next; while(q) { step1++; int step2 = 0; p = L -> Next; while(p) { step2++; if(p == q) { if(step1 == step2) break; else return 1; } p = p -> Next; } q = q -> Next; } return 0; }
*将最后一个结点与第num个结点连接起来。使用循环遍历到第num个结点,声明current指针用来保存结点。将指针p循环到最后,将p和current连接起来。
void CreateLoop(LinkList *L ,int num) { int i;//count LinkList *current; LinkList *p = L -> Next; for(i = 0;i < num; i++) { if(p == NULL) { return 0; } p = p -> Next; } current = p; while(p->Next) { p = p -> Next; } p -> Next = current; return 1; }
*声明指针p从第一个结点循环到最后一个,每次循环时用指针q,从p遍历到最后一个指针。如果有重复的结点 free()掉
Thanks> http://www.nowamagic.net/librarys/veda/detail/2241
标签:
原文地址:http://www.cnblogs.com/yangRyoung/p/4628899.html