线性表—单链表的创建、查询、插入、删除、合并

 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

 

posted @ 2018-08-22 11:42  Dawn-bin  阅读(2894)  评论(1编辑  收藏  举报