線性表—單鏈表的創建、查詢、插入、刪除、合並


 1 #define ElemType int
 2 #define OK 1
 3 #define ERROR -1
 4 #define Status int
 5 
 6 typedef struct Lnode{
 7     ElemType data;
 8     struct LNode *next;
 9 }LNode, *LinkList;
10 //LinkList 相當於 LNode *

遇到的問題

1.鏈表傳入函數中要真正改變內容要對頭節點的指針內容進行修改,  這里要區分開頭節點和頭節點的指針,

頭節點的指針是LinkList 型的可以存儲一個節點的地址,而頭節點是一個實實在在的節點,它被頭節點的指針索引。

2.上面定義的     * LinkList  其實和LNode  *    是等價的 ,   所以在開辟節點時候可以直接寫:  p = (LinkList)malloc(sizeof(LNode)); 

 

兩種創建鏈表的方式:

 1 Status CreatList_L1(LinkList *L, int n)
 2 {
 3     //尾插法創建鏈表
 4     //要將創建的鏈表返回,所以要傳入指針LinkList *L
 5     LinkList p, q;
 6     q = *L = (LinkList)malloc(sizeof(LNode));
 7     (*L)->next = NULL;
 8     for(int i=0; i < n; i++)
 9     {
10         p = (LinkList)malloc(sizeof(LNode));
11         scanf("%d", &p->data);
12         q->next = p;
13         q = p;
14     }
15     p->next = NULL;
16     return OK;
17 }//CreatList_L1
 1 Status CreatList_L2(LinkList *L, int n)
 2 {
 3     //頭插法創建鏈表
 4     (*L) = (LinkList)malloc(sizeof(LNode));
 5     (*L) ->next = NULL;         //頭插法一定加上這句
 6     LinkList s;
 7     for(int i=0; i < n; i++)
 8     {
 9         s = (LinkList)malloc(sizeof(LNode));//生成新節點
10         scanf("%d",&s->data);
11         s->next = (*L)->next;   //將新開辟的節點查到頭節點后面
12         (*L)->next = s;
13     }
14     return OK;
15 }//CreatList_L2

查詢鏈表第i個位置的元素,並返回其值:

 1 Status GetElem_L(LinkList L, int i, ElemType *e)
 2 {
 3     //L為帶頭節點的單鏈表的頭指針
 4     //但第i個元素存在時,其值賦給e並返回OK,否則返回ERROR
 5     LinkList p = L;   //初始化,p指向第1個節點
 6     int j = 0;        //計數器
 7     while(p && j < i) //順時針向后查找,直到p指向第i個元素或p為空
 8     {
 9         p = p->next;
10         j++;
11     }
12     if(!p || j > i)   //第i個元素不存在
13         return ERROR;
14     *e = p->data;      //取第i個元素
15     return OK;
16 }//GetElem_L

插入:

 1 Status ListInsert_L(LinkList L, int i, ElemType e)
 2 {
 3     //在帶頭節點的單鏈線性表L第i個位置之前插入元素e
 4     LinkList p = L, s;
 5     int j = 0;
 6     while(p && j < i-1)    //尋找第i個節點,並令p指向其前驅
 7     {
 8         p = p->next;
 9         j++;
10     }
11     if(!p || j > i - 1)    //i小於1或着大於表長+1
12         return ERROR;
13     s = (LinkList)malloc(sizeof(LNode));  //生成新節點
14     s->data = e;                          //給新節點賦值
15     s ->next = p->next;                   //新節點指向第i個節點
16     p->next = s;                          //第i-1個節點指向新節點
17     return OK;
18 }//ListInsert_L

刪除:

 1 Status ListDelete_L(LinkList L, int i, ElemType *e)
 2 {
 3     //在帶頭節點的單鏈線性表L中,刪除第i個元素,並由e返回其值
 4     LinkList p = L, q;
 5     int j = 0;
 6     while(p && j < i-1)    //尋找第i個元素,並令p指向其前驅
 7     {
 8         p  = p->next;
 9         j++;
10     }
11     if(!p || j > i-1)       //刪除位置不合理
12         return ERROR;
13     q = p->next;            //q指向刪除節點
14     *e = q->data;           //e保存其值
15     p -> next = q->next;    //移動指針跳過該節點
16     free(q);                //釋放空間
17     return OK;
18 }//ListDelete_L

合並:

 1 void MergeList_L(LinkList La, LinkList Lb, LinkList *Lc)
 2 {
 3     //已知單鏈線性表La和Lb的元素按值非遞減排列
 4     //歸並La和Lb得到新的單鏈線性表Lc,Lc的元素也按值非遞減排列
 5     LinkList pa = La->next;
 6     LinkList pb = Lb->next;
 7     (*Lc) = La;             //用La的頭節點作為Lc的頭節點
 8     LinkList pc = *Lc;
 9     while(pa && pb)      //與順序表類似
10     {
11         if(pa->data <= pb->data)
12         {
13             pc->next = pa;
14             pc = pa;
15             pa = pa->next;
16         }
17         else
18         {
19             pc->next = pb;
20             pc = pb;
21             pb = pb->next;
22         }
23     }
24     pc->next = pa ? pa : pb;  //插入剩余段
25     free(Lb);                 //釋放Lb的頭節點
26 }//MergeList_L

下面是完整代碼,可以試一下:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 #define ElemType int
  5 #define OK 1
  6 #define ERROR -1
  7 #define Status int
  8 
  9 typedef struct Lnode{
 10     ElemType data;
 11     struct LNode *next;
 12 }LNode, *LinkList;
 13 //LinkList 相當於 LNode *
 14 
 15 Status CreatList_L1(LinkList *L, int n)
 16 {
 17     //尾插法創建鏈表
 18     //要將創建的鏈表返回,所以要傳入指針LinkList *L
 19     LinkList p, q;
 20     q = *L = (LinkList)malloc(sizeof(LNode));
 21     (*L)->next = NULL;
 22     for(int i=0; i < n; i++)
 23     {
 24         p = (LinkList)malloc(sizeof(LNode));
 25         scanf("%d", &p->data);
 26         q->next = p;
 27         q = p;
 28     }
 29     p->next = NULL;
 30     return OK;
 31 }//CreatList_L1
 32 
 33 Status CreatList_L2(LinkList *L, int n)
 34 {
 35     //頭插法創建鏈表
 36     (*L) = (LinkList)malloc(sizeof(LNode));
 37     (*L) ->next = NULL;         //頭插法一定加上這句
 38     LinkList s;
 39     for(int i=0; i < n; i++)
 40     {
 41         s = (LinkList)malloc(sizeof(LNode));//生成新節點
 42         scanf("%d",&s->data);
 43         s->next = (*L)->next;   //將新開辟的節點查到頭節點后面
 44         (*L)->next = s;
 45     }
 46     return OK;
 47 }//CreatList_L2
 48 
 49 Status GetElem_L(LinkList L, int i, ElemType *e)
 50 {
 51     //L為帶頭節點的單鏈表的頭指針
 52     //但第i個元素存在時,其值賦給e並返回OK,否則返回ERROR
 53     LinkList p = L;   //初始化,p指向第1個節點
 54     int j = 0;        //計數器
 55     while(p && j < i) //順時針向后查找,直到p指向第i個元素或p為空
 56     {
 57         p = p->next;
 58         j++;
 59     }
 60     if(!p || j > i)   //第i個元素不存在
 61         return ERROR;
 62     *e = p->data;      //取第i個元素
 63     return OK;
 64 }//GetElem_L
 65 
 66 Status ListInsert_L(LinkList L, int i, ElemType e)
 67 {
 68     //在帶頭節點的單鏈線性表L第i個位置之前插入元素e
 69     LinkList p = L, s;
 70     int j = 0;
 71     while(p && j < i-1)    //尋找第i個節點,並令p指向其前驅
 72     {
 73         p = p->next;
 74         j++;
 75     }
 76     if(!p || j > i - 1)    //i小於1或着大於表長+1
 77         return ERROR;
 78     s = (LinkList)malloc(sizeof(LNode));  //生成新節點
 79     s->data = e;                          //給新節點賦值
 80     s ->next = p->next;                   //新節點指向第i個節點
 81     p->next = s;                          //第i-1個節點指向新節點
 82     return OK;
 83 }//ListInsert_L
 84 
 85 Status ListDelete_L(LinkList L, int i, ElemType *e)
 86 {
 87     //在帶頭節點的單鏈線性表L中,刪除第i個元素,並由e返回其值
 88     LinkList p = L, q;
 89     int j = 0;
 90     while(p && j < i-1)    //尋找第i個元素,並令p指向其前驅
 91     {
 92         p  = p->next;
 93         j++;
 94     }
 95     if(!p || j > i-1)       //刪除位置不合理
 96         return ERROR;
 97     q = p->next;            //q指向刪除節點
 98     *e = q->data;           //e保存其值
 99     p -> next = q->next;    //移動指針跳過該節點
100     free(q);                //釋放空間
101     return OK;
102 }//ListDelete_L
103 
104 void MergeList_L(LinkList La, LinkList Lb, LinkList *Lc)
105 {
106     //已知單鏈線性表La和Lb的元素按值非遞減排列
107     //歸並La和Lb得到新的單鏈線性表Lc,Lc的元素也按值非遞減排列
108     LinkList pa = La->next;
109     LinkList pb = Lb->next;
110     (*Lc) = La;             //用La的頭節點作為Lc的頭節點
111     LinkList pc = *Lc;
112     while(pa && pb)      //與順序表類似
113     {
114         if(pa->data <= pb->data)
115         {
116             pc->next = pa;
117             pc = pa;
118             pa = pa->next;
119         }
120         else
121         {
122             pc->next = pb;
123             pc = pb;
124             pb = pb->next;
125         }
126     }
127     pc->next = pa ? pa : pb;  //插入剩余段
128     free(Lb);                 //釋放Lb的頭節點
129 }//MergeList_L
130 
131 int main()
132 {
133     int n;
134     LinkList L, p, s;
135     scanf("%d",&n);
136     CreatList_L1(&L, n);
137     printf("\n~~~\n");
138     p = L->next;
139     while( p != NULL){
140         printf("%d ",p->data);
141         p = p->next;
142     }
143     printf("\n");
144 
145     int i, e;
146     printf("查詢位置: ");
147     scanf("%d",&i);
148     GetElem_L(L, i, &e);
149     printf("e == %d\n",e);
150 
151     printf("插入位置、元素:");
152     scanf("%d%d",&i,&e);
153     ListInsert_L(L, i, e);
154     p = L->next;
155     while(p){
156         printf("%d ",p->data);
157         p = p->next;
158     }
159     printf("\n");
160 
161     printf("刪除位置:");
162     scanf("%d",&i);
163     ListDelete_L(L, i, &e);
164     printf("e == %d\n",e);
165 
166     int a[ ]= {3, 5, 8, 11};
167     int b[ ]= {2, 6, 8, 9, 11, 15, 20};
168     LinkList La, Lb;
169     La = (LinkList)malloc(sizeof(LNode));
170     Lb = (LinkList)malloc(sizeof(LNode));
171     La->next = Lb->next = NULL;
172     p = La;
173     for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
174     {
175         s = (LinkList)malloc(sizeof(LNode));
176         s->data = a[i];
177         p->next = s;
178         p = s;
179     }
180     p->next = NULL;
181 
182     p = Lb;
183     for(int i = 0; i<sizeof(b)/sizeof(b[0]); i++)
184     {
185         s = (LinkList)malloc(sizeof(LNode));
186         s->data = b[i];
187         p->next = s;
188         p = s;
189     }
190     p->next = NULL;
191 
192     printf("La = ");
193     p = La->next;
194     while(p)
195     {
196         printf("%d ",p->data);
197         p = p->next;
198     }
199     printf("\n");
200     p = La->next;
201 
202     printf("Lb = ");
203     p = Lb->next;
204     while(p)
205     {
206         printf("%d ",p->data);
207         p = p->next;
208     }
209     printf("\n");
210 
211     LinkList Lc;
212     MergeList_L(La, Lb, &Lc);
213 
214     printf("MergeList = ");
215     p = Lc->next;
216     while(p)
217     {
218         printf("%d ", p->data);
219         p = p->next;
220     }
221     printf("\n");
222 
223 
224     return 0;
225 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM