单链表
2016-03-07 00:00
323 查看
基本操作: 创建、查找、删除、插入
*用标尺法求未知长度单链表的中间节点
**声明2个指针,search,mid。search指针的移动速度是mid指针的2倍,当search指针到达链表结尾时。mid指针到达链表中间。
*第二种方法 和嵌套循环类似 设2个指针q、p,p走一步,q每次从头走到结束。如果有环,结点相同时步数不相等。
Thanks> http://www.nowamagic.net/librarys/veda/detail/2241
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
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)