天天看點

雙向連結清單

雙向連結清單

2015-04-04 Lover雪兒

1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define OK        1
  5 #define ERROR    0
  6 #define TRUE    1
  7 #define FALSE    0
  8 
  9 typedef char    ElemType;
 10 typedef int        Status;
 11 
 12 //雙向連結清單結構體定義
 13 typedef struct DualNode
 14 {
 15     ElemType data;
 16     struct DualNode *prior;
 17     struct DualNode *next;
 18 }DualNode, *DuLinkList;
 19 
 20 /**************************************************
 21         初始化連結清單
 22 **************************************************/
 23 Status Init_List(DuLinkList *L)
 24 {
 25     DualNode *p, *q;
 26     int i;
 27     //生成 頭結點
 28     *L = (DuLinkList)malloc(sizeof(DualNode));
 29     if( !(*L) ){
 30         return ERROR;
 31     }
 32     (*L)->next = (*L)->prior = (*L);
 33     p = (*L);    //頭結點
 34     
 35     //生成連結清單
 36     for(i = 0; i<26; i++){
 37         q = (DualNode *)malloc(sizeof(DualNode));
 38         if(!q){
 39             return ERROR;
 40         }
 41         q->data = 'A' + i;  //依次給連結清單指派 字元表
 42 
 43         q->prior = p;  
 44         p->next = q;
 45         q->next = (*L)->next;
 46         
 47         p = q;
 48     }
 49     p->next = (*L)->next;    //讓尾結點的後向指針指向頭結點指向的位址,即第一個單元
 50     (*L)->next->prior = p;    //讓頭結點的前向指針指向尾節點
 51     return OK;
 52 }
 53 /**************************************************
 54     判斷空連結清單
 55 **************************************************/
 56 Status List_Empty(DuLinkList *L){
 57     if((*L)->next == (*L) && (*L)->prior == (*L))
 58         return TRUE;
 59     else
 60         return FALSE;
 61 }
 62 /**************************************************
 63     計算L中的個數
 64 **************************************************/
 65 int List_Length(DuLinkList *L){
 66     int i = 0;
 67     DuLinkList p = (*L)->next;
 68     while(p != (*L))    //檢測是否已經循環了一遍
 69     {
 70         p = p->next;
 71         ++i;
 72     }
 73     i ++;
 74     return i;
 75 }
 76 
 77 /**************************************************
 78     排序算法,連結清單前後/後向移動i個結點
 79 **************************************************/
 80 void Caesar(DuLinkList *L, int i){
 81     if(i > 0){
 82         do{
 83             (*L) = (*L)->next; 
 84         }while(--i);
 85     }
 86     if(i < 0){
 87         do{
 88             (*L) = (*L)->prior;
 89         }while(++i);
 90     }
 91 }
 92 
 93 /**************************************************
 94     循環列印連結清單中的資料
 95 **************************************************/
 96 void printf_list(DuLinkList *L){
 97     DuLinkList p = (*L)->next;
 98     printf("%c ",(*L)->data);
 99     while(p != (*L)){
100         printf("%c ",p->data);
101         p = p->next;
102     }
103     printf("\n\n");
104 }
105 
106 /**************************************************
107     向連結清單中插入資料
108 **************************************************/
109 Status List_Insert(DuLinkList *L,int i,ElemType dat){
110     DuLinkList q, p = (*L),tmp;
111     if(i < 1 || i>List_Length(L))
112         return ERROR;
113     while(--i){
114         p = p->next;
115     }
116     q = (DuLinkList)malloc(sizeof(DualNode));
117     q->data = dat;
118         
119     tmp = p->next;
120     p->next = q;
121     q->prior = p;
122     q->next = tmp;
123     tmp->prior = q;
124     return OK;
125 }
126 
127 /**************************************************
128     從連結清單中删除資料
129 **************************************************/
130 Status List_delete(DuLinkList *L,int i){
131     DuLinkList p = (*L);
132     if(i < 1 || i>List_Length(L))
133         return ERROR;
134     if(i == 1){
135         Caesar(L, 1);    //排序
136         //printf_list(L);
137         i = List_Length(L) + 1;
138     }
139     //printf_list(L);
140     while(--i){
141         p = p->next;
142     }
143     p->next->prior = p->prior;
144     p->prior->next = p->next;
145     free(p);
146     
147     return OK;
148 }
149 
150 /**************************************************
151         清空連結清單
152 **************************************************/
153 void Clear_List(DuLinkList *L){
154     DuLinkList q, p=(*L)->next;
155     while(p != (*L)){
156         q = p->next;
157         free(p);
158         p = q;
159     }
160     (*L)->prior = (*L)->next = *L;
161     printf("\n成功清空雙向連結清單!\n");
162 }
163 
164 /**************************************************
165         删除連結清單
166 **************************************************/
167 void Destroy_List(DuLinkList *L){
168     DuLinkList q, p=(*L)->next;
169     while(p != (*L)->next){
170         q = p->next;
171         free(p);
172         p = q;
173     }
174     free(*L);
175     *L = NULL;
176     printf("\n成功銷毀雙向連結清單!\n");
177 }
178 /**************************************************
179         主循環
180 **************************************************/
181 int main(void)
182 {
183     DuLinkList L,p;
184     int  n , m ;
185     char k;
186     
187     Init_List(&L);  //初始化連結清單
188     p = L->next;
189 
190     printf("雙向連結清單總共有%d個元素:\n",List_Length(&p));
191     printf_list(&p); //循環列印連結清單元素
192 
193     while(1){
194         printf("0:退出并銷毀連結清單\n1:列印出目前連結清單\n2:插入/删除結點\n3:連結清單有序移動\n\n");
195         scanf("%d",&n);
196         if(n == 0){
197             break;
198         }else if(n == 1){
199             printf_list(&p); //循環列印連結清單元素
200         }else if(n == 2){
201             printf_list(&p); //循環列印連結清單元素
202             while(1){
203                 printf("0:退出\n1:插入資料\n2:删除資料\n");
204                 scanf("%d",&n);
205                 if(n == 0){
206                     break;
207                 }else if(n == 1){
208                     printf("請輸入要插入的位置、資料,格式:m k\n");
209                     scanf("%d %c",&m,&k);
210                     List_Insert(&p,m,k);
211                     printf_list(&p); //循環列印連結清單元素
212                 }else if(n == 2){
213                     printf("請輸入要删除的位置\n");
214                     scanf("%d",&m);
215                     List_delete(&p,m);
216                     printf_list(&p); //循環列印連結清單元素
217                 }else{
218                     printf("請正确輸入指令,謝謝!!!\n");
219                 }
220             }
221         }else if(n == 3){
222             while(1){
223                 printf("請輸入一個整數[正數(前向移動)/負數(後向移動)/0(退出)]:\n");
224                 scanf("%d",&n);
225                 if(n == 0)
226                     break;    
227                 Caesar(&p, n);    //排序
228                 printf_list(&p); //循環列印連結清單元素
229             }
230         }else{
231             printf("請正确輸入指令,謝謝!!!\n");
232         }
233     }
234     printf_list(&(L->next)); //循環列印連結清單元素
235     Destroy_List(&L);
236     return 0;
237 }           
雙向連結清單
下一篇: Golang IO操作