数据结构学习第三天
19:28:16 2019-08-18
今天稍微早点。
00:51:49 2019-08-21
增加了对双链表的测试
17:30:49 2019-08-21
增加了对栈的测试
增加了对队列的测试
双链表
DList.h
1 #ifndef _DLIST_H 2 #define _DLIST_H 3 #define len sizeof(struct Node) 4 #include<malloc.h> 5 typedef struct Node* PtrToNode; 6 typedef PtrToNode DList; 7 typedef PtrToNode DPosition; 8 struct Node 9 { 10 int Element; 11 DPosition Prior; 12 DPosition Next; 13 }; 14 DList MakeEmety(DList L); 15 int IsEmpty(DList L); 16 int IsLast(DPosition P, DList L); 17 DPosition Find(int Element, DList L); 18 void Delete(int Element, DList L); 19 DPosition FindPrevious(int Element, DList L); 20 void InsertBefore(int Element,DList L, DPosition P); 21 void InsertAfter(int Element, DList L, DPosition P); 22 void DeleteList(DList L); 23 DPosition Header(DList L); 24 DPosition First(DList L); 25 #endif // !_DLIST_H
DList.c
1 #include"DList.h" 2 extern struct Node; 3 DList MakeEmety(DList L) 4 { 5 L = (DList)malloc(len); 6 L->Element = 0; 7 L->Prior = NULL; 8 L->Next = NULL; 9 return L; 10 } 11 12 int IsEmpty(DList L) 13 { 14 return L->Next == NULL; 15 } 16 17 int IsLast(DPosition P, DList L) 18 { 19 return P->Next == NULL; 20 } 21 22 DPosition Find(int Element, DList L) 23 { 24 DPosition P = L->Next; 25 /*while (P!=NULL) 26 { 27 if (P->Element == Element) 28 return P; 29 else 30 P = P->Next; 31 } 32 return NULL;*/ 33 while (P!=NULL&&P->Element!=Element) 34 { 35 P = P->Next; 36 } 37 return P; 38 } 39 40 void Delete(int Element, DList L) 41 { 42 /*DPosition P1, P2; 43 P1=P2= FindPrevious(Element, L); //利用单链表的思想来删除 但要注意删除是否为最后一个元素 44 P2 = P1->Next; //因为单链表只向后 而双链表有一个指向前面的指针 最后一个元素的后驱元指针为NULL 45 if (IsLast(P1->Next,L)) 46 { 47 P1->Next =NULL; 48 } 49 else 50 { 51 P1->Next = P1->Next->Next; 52 P1->Next->Prior = P1; 53 } 54 free(P2);*/ 55 //利用双链表来删除 56 DPosition P1; 57 P1 = Find(Element, L); //利用双链表的特点来删除 58 P1->Prior->Next = P1->Next; 59 if (!IsLast(P1, L)) 60 { 61 P1->Next->Prior = P1->Prior; //同时也要注意是否是尾节点 62 } 63 free(P1); 64 } 65 66 DPosition FindPrevious(int Element, DList L) 67 { 68 DPosition P = L; 69 /*while (P->Next!=NULL) 70 { 71 if (P->Next->Element==Element) 72 return P; 73 else 74 P = P->Next; 75 } 76 return NULL;*/ 77 while (P->Next!=NULL&&P->Next->Element!=Element) 78 { 79 P = P->Next; 80 } 81 return P; 82 } 83 84 void InsertBefore(int Element, DList L, DPosition P) 85 { 86 DPosition P1 = (DPosition)malloc(len); 87 P1->Element=Element; 88 P1->Prior = P->Prior; 89 P1->Next = P; 90 P->Prior->Next = P1; 91 P->Prior = P1; 92 } 93 94 void InsertAfter(int Element, DList L, DPosition P) 95 { 96 DPosition P1 = (DPosition)malloc(len); 97 P1->Element = Element; 98 P1->Prior = P; 99 P1->Next = P->Next; 100 P->Next = P1; 101 if (!IsLast(P1, L)) //做完上面的 P已经不是尾节点了 102 { 103 P1->Next->Prior = P1; //如果是插在末尾 这句话要删掉 //写成这样就是为了末尾的特殊情况 104 } //可以看出 因为双链表具有指向前的指针 导致插入和删除出现了特殊情况 105 } 106 107 void DeleteList(DList L) 108 { 109 DPosition P1, P2; 110 P1 = P2 = L->Next; 111 while (P2 != NULL) 112 { 113 P2 = P1->Next; 114 free(P1); 115 P1 = P2; 116 } 117 } 118 119 DPosition Header(DList L) 120 { 121 return L; 122 } 123 124 DPosition First(DList L) 125 { 126 return L->Next; 127 }
main.c
1 #include<stdio.h> 2 #include<malloc.h> 3 #include"DList.h" 4 int main() 5 { 6 DList L = NULL; 7 L = MakeEmety(L); 8 printf("%10d %10d\n", IsEmpty(L), IsLast(L, L)); 9 DPosition P = (DPosition)malloc(len); 10 L->Next = P; 11 P->Element = 20; 12 P->Next = NULL; 13 P->Prior = L; 14 printf("%10d %10d\n", P->Element, IsLast(P, L)); 15 InsertBefore(25, L, P); 16 printf("%10d %10d\n",L->Next->Element, IsLast(L->Next, L)); 17 printf("%10d %10d\n", L->Next->Element, P->Prior->Element); 18 printf("%10d\n", Find(20, L)->Element); 19 Delete(25, L); 20 printf("%10d\n", L->Next->Element); 21 InsertAfter(30, L, P); 22 printf("%10d %10d\n",P->Next->Element,P->Next->Prior->Element); 23 Delete(20, L); 24 printf("%10d\n", IsEmpty(L)); 25 DeleteList(L); 26 return 0; 27 }
测试结果
循环单链表是将末尾元素中的指针指向第一个节点
循环双链表是将末尾元素中的next指针指向第一个节点 ,第一个节点中的prior指针指向最后一个节点
栈的链表实现
LIFO(后进先出)
Stack.h
1 #ifndef _STACK_H 2 #define _STACK_H 3 #define len sizeof(struct Node) 4 struct Node; 5 typedef struct Node* PtrToNode; 6 typedef PtrToNode Stack; 7 int IsEmpty(Stack S); 8 Stack CreatStack(); 9 void DisposeStack(Stack S); 10 void MakeEmpty(Stack S); 11 void Push(int Element, Stack S); 12 int Top(Stack S); 13 void Pop(Stack S); 14 #endif // !_STACK_H
Stack.c
1 #include"Stack.h" 2 #include<stdio.h> 3 #include<malloc.h> 4 struct Node 5 { 6 int Element; 7 PtrToNode Next; 8 }; 9 10 int IsEmpty(Stack S) 11 { 12 return S->Next == NULL; 13 } 14 15 Stack CreatStack() 16 { 17 Stack S = (Stack)malloc(len); 18 S->Next = NULL; 19 MakeEmpty(S); 20 return S; 21 } 22 23 void DisposeStack(Stack S) 24 { 25 while (!IsEmpty(S)) 26 { 27 Pop(S); 28 } 29 free(S); 30 } 31 32 void MakeEmpty(Stack S) 33 { 34 while (!IsEmpty(S)) 35 { 36 Pop(S); 37 } 38 } 39 40 void Push(int Element, Stack S) 41 { 42 PtrToNode P = (PtrToNode)malloc(len); 43 P->Element = Element; 44 P->Next = S->Next; 45 S->Next = P; 46 } 47 48 int Top(Stack S) 49 { 50 if (IsEmpty(S)) 51 { 52 printf("No Element\n"); 53 return -1; 54 } 55 return S->Next->Element; 56 } 57 58 void Pop(Stack S) 59 { 60 PtrToNode P=S->Next; 61 if (P) 62 { 63 S->Next = S->Next->Next; 64 free(P); 65 } 66 else 67 { 68 printf("stack is empty\n"); 69 } 70 }
main.c
1 #include<stdio.h> 2 #include"Stack.h" 3 4 int main() 5 { 6 Stack S=NULL; 7 S = CreatStack(); 8 printf("%10d %10d\n", Top(S),IsEmpty(S)); 9 Push(10, S); 10 printf("%10d %10d\n", Top(S),IsEmpty(S)); 11 Push(25, S); 12 printf("%10d\n", Top(S)); 13 Pop(S); 14 printf("%10d %10d\n", Top(S), IsEmpty(S)); 15 Pop(S); 16 printf("%10d %10d\n",Top(S),IsEmpty(S)); 17 DisposeStack(S); 18 return 0; 19 }
测试
队列的链表实现
Queue.h
1 #ifndef _QUEUE_H 2 #define _QUEUE_H 3 #define len sizeof(Node) 4 #define length sizeof(Queue) 5 struct Node; 6 struct Queue; 7 typedef struct Node* PtrToNode; 8 typedef struct Queue* HQueue; 9 int IsEmpty(HQueue H); 10 HQueue CreatQueue(); 11 void DiposeQueue(HQueue H); 12 void Enqueue(int Element, HQueue H); 13 void Dequeue(HQueue H); 14 #endif // !_QUEUE_H
Queue.c
1 #include<stdio.h> 2 #include"Queue.h" 3 #include<malloc.h> 4 struct Node 5 { 6 int Element; 7 PtrToNode Next; 8 }; 9 struct Queue 10 { 11 PtrToNode front; 12 PtrToNode rear; 13 }; 14 15 int IsEmpty(HQueue H) 16 { 17 return H->rear == NULL || H->front == NULL; 18 } 19 20 HQueue CreatQueue() 21 { 22 HQueue H= (HQueue)malloc(length); 23 H->front = NULL; 24 H->rear = NULL; 25 return H; 26 } 27 28 void DiposeQueue(HQueue H) 29 { 30 PtrToNode P1, P2; 31 P1 = P2 = H->front; 32 while (P2) 33 { 34 P2 = P1->Next; 35 free(P1); 36 P1 = P2; 37 } 38 free(H); 39 } 40 41 void Enqueue(int Element, HQueue H) 42 { 43 PtrToNode P = (PtrToNode)malloc(len); 44 P->Element = Element; 45 P->Next=NULL; 46 if (IsEmpty(H)) 47 { 48 H->front = P; 49 H->rear = P; 50 } 51 else 52 { 53 H->rear->Next = P; 54 H->rear = P; 55 } 56 } 57 58 void Dequeue(HQueue H) 59 { 60 PtrToNode P; 61 if (IsEmpty(H)) 62 { 63 printf("No Element\n"); 64 return ; 65 } 66 else 67 { 68 P = H->front; 69 /*H->front = H->front->Next; //当队列中只有一个元素时候要特殊处理 70 free(P);*/ 71 } 72 if (H->front== H->rear) 73 { 74 free(P); 75 H->front = H->rear = NULL; 76 } 77 else 78 { 79 H->front = H->front->Next; 80 free(P); 81 } 82 }
main.c
1 #include<stdio.h> 2 #include"Queue.h" 3 int main() 4 { 5 HQueue HQ=NULL; 6 HQ = CreatQueue(); 7 Dequeue(HQ); 8 printf("%10d\n", IsEmpty(HQ)); 9 Enqueue(20, HQ); 10 printf("%10d\n", IsEmpty(HQ)); 11 Dequeue(HQ); 12 printf("%10d\n", IsEmpty(HQ)); 13 DiposeQueue(HQ); 14 return 0; 15 }
测试: