单链表基本操作(可执行程序),二级指针使用必要性的初步理解
生活随笔
收集整理的這篇文章主要介紹了
单链表基本操作(可执行程序),二级指针使用必要性的初步理解
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define ERROR 0;
#define OK 1;//typedef
typedef int Status;
typedef int ElemType;
typedef struct Node//定義帶頭結點的單鏈表的節(jié)點類型
{ElemType data;struct Node *next;
}Node;
typedef struct Node *LinkList;//操作函數(shù)聲明
Status CreateListHead(LinkList*L,int n);
Status CreateListTail(LinkList *L,int n);
Status GetElem(LinkList L,int i,ElemType *e);
Status ListInsert(LinkList *L,int i,ElemType e);
Status ListDelete(LinkList*L,int i,ElemType *e);
Status DestroyList(LinkList *L);
Status ListTraverse(LinkList L);int main()
{LinkList L;int n=5;int e=0;int i=0;printf("請輸入需要產生的單鏈表長度(>=1):");scanf("%d",&n);CreateListTail(&L,n);printf("產生的單鏈表是:");ListTraverse(L);printf("請輸入你想要插入的位置和數(shù):");scanf("%d %d",&i,&e);ListInsert(&L,i,e);printf("插入后得到的新鏈表是:");ListTraverse(L);printf("你想要查看哪個位置的數(shù):");scanf("%d",&i);printf("該數(shù)是:");GetElem(L,i,&e);printf("\n");printf("你想要刪除哪個位置的數(shù):");scanf("%d",&i);ListDelete(&L,i,&e);printf("刪除以后的新鏈表是:");ListTraverse(L);printf("現(xiàn)在要銷毀鏈表釋放空間啦!\n");DestroyList(&L);}//單鏈表的整表創(chuàng)建,頭插法
Status CreateListHead(LinkList*L,int n)
{LinkList p;int i;srand(time(0));*L=(LinkList)malloc(sizeof(Node));( *L)->next=NULL;if(n<1)return ERROR;for(i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;p->next=(*L)->next;(*L)->next=p;}return OK;}
//單鏈表的整表創(chuàng)建,尾插法
Status CreateListTail(LinkList *L,int n)
{LinkList p,r;int i;*L=(LinkList)malloc(sizeof(Node));( *L)->next=NULL;r=*L;srand(time(0));for (i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;r->next=p;r=p;}r->next=NULL;return OK;
}//讀取單鏈表中的第i個元素
Status GetElem(LinkList L,int i,ElemType *e)
{int j=1;LinkList p;p=L->next;while(p&&j<i){p=p->next;++j;}if(j>i||!p)return ERROR;*e=p->data;printf("%d",*e);return OK;
}//在單鏈表中第i個位置之前插入一個新節(jié)點e
Status ListInsert(LinkList *L,int i,ElemType e)
{int j=1;LinkList p,s;p=*L;while(p&&j<i){p=p->next;++j;}if (!p||j>i)return ERROR;s=(LinkList)malloc(sizeof(Node));s->data=e;s->next=p->next;p->next=s;return OK;
}//刪除單鏈表的第i個元素,并用e返回其值
Status ListDelete(LinkList*L,int i,ElemType *e)
{int j=1;LinkList p,q;p=*L;while(p->next&&j<i){p=p->next;++j;}if (!(p->next)||j>i)return ERROR;q=p->next;p->next=q->next;* e=q->data;free(q);return OK;
}//銷毀單鏈表
Status DestroyList(LinkList *L)
{LinkList p,q;p=(*L)->next;while(p){q=p->next;free(p);p=q;}free(*L);*L=NULL;printf("鏈表銷毀成功!");return OK;
}
//打印單鏈表
Status ListTraverse(LinkList L)
{LinkList p;p=L->next;while(p){printf("%d ",p->data);p=p->next;}printf("\n");return OK;
}
程序測試結果:
關于二級指針使用的必要性,我是這樣理解的:
很多操作其實使用一級指針也可以實現(xiàn),但是在需要改變一級指針的值是就必須使用二級指針,例如,需要刪除頭結點或者生成鏈表時,L的值就需要變化,那么此時只有傳入二級指針才能達到修改L的值的目的,這種情況下傳入&L也是可行的。
下面舉兩個例子說明一下:
(1)
在鏈表已經生成的情況下,修改ListInsert函數(shù)為:
Status ListInsert(LinkList L,int i,ElemType e) {int j=1;LinkList p,s;p=L;while(p&&j<i){p=p->next;++j;}if (!p||j>i)return ERROR;s=(LinkList)malloc(sizeof(Node));s->data=e;s->next=p->next;p->next=s;return OK; }程序仍然可以得到正確的結果。
(2)
但是在生成鏈表時,若只傳入一級指針,即修改CreateListTail為:
Status CreateListTail(LinkList L,int n) {LinkList p,r;int i;L=(LinkList)malloc(sizeof(Node));L->next=NULL;r=L;srand(time(0));for (i=0;i<n;i++){p=(LinkList)malloc(sizeof(Node));p->data=rand()%100+1;r->next=p;r=p;}r->next=NULL;return OK; }則運行程序時,CodeBlocks會停止工作,這是因為在生成鏈表階段,需要將L的值傳出到主函數(shù),供后面的鏈表打印函數(shù)ListTraverse調用。若此處只傳入一級指針,則CreateListTail函數(shù)調用結束以后,L的值并沒有改變,相當于L仍指向主函數(shù)中定義時所指向的位置(野指針或者指向NULL,暫時還不是很清楚如果不初始化指向哪里),則后續(xù)調用打印函數(shù)會出錯。
總結:需要修改L的值時,必須傳入二級指針即func(LinkList *L),其他情況下傳一級指針即func(LinkList L)就ok。
總結
以上是生活随笔為你收集整理的单链表基本操作(可执行程序),二级指针使用必要性的初步理解的全部內容,希望文章能夠幫你解決所遇到的問題。