链表操作--指针传递 测试与学习

来源:互联网 发布:手机淘宝怎样查看物流 编辑:程序博客网 时间:2024/05/21 19:39

链表操作,测试下 通过 指向结点的指针以及 指向结点指针的指针 完成 链表操作。

//链表的实现#include <stdio.h>#include <malloc.h>#define ElemType int#define LIST_INIT_SIZE 20#define OK 1#define ERROR 0typedef struct Node{int data;struct Node *next;}Node, *LinkList;int CreateList(LinkList *list, int n);int InsertList(LinkList list, int pos, int n);int DelList(LinkList *list, int pos, int *n);int MergeList(LinkList *des_list, LinkList *src_list);//将src_list合并至des_list中,两列表有序 从小到大排列int ListTraverse(LinkList list); //可传指针,减少复制int ListLength(LinkList list);int DestroyList(LinkList *list);//摧毁链表,表头+结点int ClearList(LinkList *list);//置为空表int InsertList_p(LinkList *list, int pos, int n); int LocatePos(LinkList list, int i, LinkList *des);//用des指向list中第i个结点int MakeNode(LinkList *node, ElemType e);//int InsFirst(LinkList *list, LinkList p);int DelFirst(LinkList list, LinkList p);#define _POINT_int main(){LinkList list_q = NULL;LinkList list_p = NULL;LinkList des = NULL;int n, m;CreateList(&list_q, 3);printf("create list,length:%d \n", ListLength(list_q));ListTraverse(list_q);MakeNode(&des, 5);LocatePos(list_q, 2, &des);InsFirst(&list_q, des);printf("first insert,length:%d \n", ListLength(list_q));ListTraverse(list_q);DelFirst(list_q, des);printf("first del,length:%d \n", ListLength(list_q));ListTraverse(list_q);CreateList(&list_p, 3);printf("create list,length:%d \n", ListLength(list_q));ListTraverse(list_p);MergeList(&list_p, &list_q);printf("after merge,length:%d \n", ListLength(list_p));ListTraverse(list_p);ClearList(&list_p);printf("after clear,length:%d \n", ListLength(list_p));ListTraverse(list_p);//CreateList(&list_q, 3);//list_q在Mergelist中被释放,需重建#ifndef _POINT_if (InsertList(list_p, 1, 3)){ListTraverse(list_p);printf(" 1 insert length:%d \n", ListLength(list_p));}if (InsertList(list_p, 3, 6)){ListTraverse(list_p);printf(" 2 insert length:%d \n", ListLength(list_p));}if (InsertList(list_p, ListLength(list_p) + 1, 5)){ListTraverse(list_p);printf(" 3 insert length:%d \n", ListLength(list_p));}if (InsertList(list_p, ListLength(list_p) + 2, 5)){ListTraverse(list_p);printf(" 4 insert length:%d \n", ListLength(list_p));}if (InsertList(list_p, ListLength(list_p) + 12, 5)){ListTraverse(list_p);printf(" 4 insert length:%d \n", ListLength(list_p));}#elseif (InsertList_p(&list_p, 1, 3))//边界测试{printf("1st insert length:%d \n", ListLength(list_p));ListTraverse(list_p);}if (InsertList_p(&list_p, 3, 6)){printf("2nd insert length:%d \n", ListLength(list_p));ListTraverse(list_p);}if (InsertList_p(&list_p, ListLength(list_p) + 1, 5))//边界测试{printf("3th insert length:%d \n", ListLength(list_p));ListTraverse(list_p);}if (DelList(&list_p, 1, &n))//边界测试{printf("del 1st num:%d\n", n);ListTraverse(list_p);}if (DelList(&list_p, ListLength(list_p), &m))//边界测试{printf("del last num:%d\n", m);ListTraverse(list_p);} if (InsertList_p(&list_p, ListLength(list_p) + 2, 5)) //边界测试{printf("insert len+2 length:%d \n", ListLength(list_p));ListTraverse(list_p);}#endifreturn 0;}int CreateList(LinkList *list, int n) //创建带表头的链表  从尾到头{int i = 0;LinkList p;*list = (LinkList)malloc(sizeof(Node));//创建头结点if(!(*list))return ERROR;(*list)->next = NULL;for (i = 0; i < n; i++){p = (LinkList)malloc(sizeof(Node));if (!p)return ERROR;printf("input data:");scanf_s("%d",&p->data);p->next = (*list)->next;(*list)->next = p;}return OK;}int ListTraverse(LinkList list){LinkList p = list->next;//指向第一个节点while(p){printf("%d ",p->data);p = p->next;}printf("\n");return OK;}/*在第pos位置之前添加,1<=n<= length +1*/int InsertList(LinkList list, int pos, int n) {int i = 0;LinkList p = list; //指向头LinkList temp;if(pos < 1)return ERROR;for (i = 0; i< pos-1 && p;i++) //使指针 指向 pos - 1 的位置, !p保证 pos-1 <=length+1{p = p->next;}//退出3中可能 (1)i == pos -1  正确 (2)p == null (3)兼有  (2)(3)为超过length+1if(!p || i != pos-1) {printf("beyond the limit\n");return ERROR; //确认指针 指向 pos - 1 的位置}temp = (LinkList)malloc(sizeof(Node));if (!temp){return ERROR;}temp->data = n;temp->next = p->next;p->next = temp;return OK;}int DelList(LinkList *list, int pos, int *n){int i;LinkList p = *list;//p指向标头LinkList q;if (pos < 1)return ERROR;for(i = 0; (i < pos-1)&&(p->next); i++) //指向pos-1{p = p->next;//边界检测}if ((i != pos-1)||(!(p->next)))return ERROR;q = p->next;*n = q->data;p->next = q->next;free(q);return OK;}int ListLength(LinkList list){int length = 0;LinkList p = list;if (!list)//边界检测return ERROR;while (p->next){length++;p = p->next; }return length;}int InsertList_p(LinkList *list, int pos, int n) {int i = 0;LinkList *p = list; //指向头LinkList temp;    LinkList q = *list;if (pos < 1){return ERROR;}for (i = 0; i < pos-1 && q ;i++) //指向 pos - 1 的位置{q = q->next;}if ( !q || i != pos-1 ){printf("beyond limit\n");return ERROR;}temp = (LinkList)malloc(sizeof(Node));temp->data = n;temp->next = q->next;q->next = temp;return OK;}int MergeList(LinkList *des_list, LinkList *src_list)//两列表有序 从小到大排列{LinkList des = *des_list;//指向头结点LinkList p_des = (*des_list)->next;//指向第一个结点LinkList p_src = (*src_list)->next;while(p_des && p_src){if (p_des->data <= p_src->data){des->next = p_des;des = des->next;p_des = p_des->next;}else{des->next = p_src;des = des->next;p_src = p_src->next;}}des->next = p_des ? p_des : p_src;//free(*src_list);//释放源链表的头结点return OK;}int DestroyList(LinkList *list)//从表头开始释放{LinkList *t_list = list;//*t_list为 标头LinkList p;while (*t_list){p = (*t_list)->next;free(*t_list);*t_list = p;}*list = NULL;  //收尾,是list指向空return OK;}int ClearList(LinkList *list)//从第一个结点开始释放{LinkList p = (*list)->next;//指向第一个节点LinkList q;while(p){q = p->next;free(p);p = q;}(*list)->next = NULL;return OK;}int LocatePos(LinkList list, int pos, LinkList *des)//用des指向list中第pos个结点{LinkList p = list;//p指向头结点int i = 0;if (pos < 1)return ERROR;while(p && i<pos)//p指向 pos位置,pos次{p = p->next;i++;}if(!p || i != pos)return ERROR;(*des)->next = p->next;(*des)->data = p->data;return OK;}int MakeNode(LinkList *node, ElemType e){*node = (LinkList)malloc(sizeof(Node));if (!*node)return ERROR;(*node)->next = NULL;(*node)->data = e;return OK;}int InsFirst(LinkList *list, LinkList p)//将p指向的结点添加至list第一个位置{LinkList t_list = (*list)->next;//指向第一个节点(*list)->next = p;p->next = t_list;//p指向结点为第一结点return OK;}int DelFirst(LinkList list, LinkList p)//p删除第一个结点,并用p指向该结点{ LinkList head = list;LinkList q = head->next;//p指向第一个节点if (!q)return ERROR;head->next = q->next;return OK;}

测试结果:


小结:

 对比  int InsertList(LinkList list, int pos, int n);  与   int InsertList_p(LinkList *list, int pos, int n);

上例中对 链表进行插入操作时,既可以 传递 LinkList p_node变量--指向结点的指针,也可传递 LinkList *list指向 链表的指针。

理解不同传递参数的意义:

传递 LinkList p_node时,理解为 传递头结点的地址。  (LinkList == Node*)

传递 LinkList *list 时,理解为传递的为链表的地址。 (链表为指向头结点的指针/地址)

传递不同参数的目的:

获取参数拷贝,还是获取地址 修改该参数的内容。




原创粉丝点击