線性表單鏈表的實現
一、基本操作
1)定義
typedef int ElementType;
typedef LNode *PtrToLNode;//指向結點的指針
struct LNode{
ElementType data;
PtrToLNode next;
};
typedef PtrToLNode List;
2)初始化
List L;
L=(LNode *)malloc(sizeof(LNode));//生成頭結點
L->next=NULL;
3)單鏈表的建立
①頭插法
void CreateListF(List *L){
int i;
for(i=1;i<=5;i++){
PtrToLNode q;
q=(PtrToLNode)malloc(sizeof(Node));//初始化!!!
q->data=i;
q->next=(*L)->next;
(*L)->next=q;
}
}
②尾插法
void CreateListR(List *L){
int i;
PtrToLNode r;//尾指針
r=*L;
for(i=1;i<=5;i++){
PtrToLNode q;
q=(PtrToLNode)malloc(sizeof(Node));
q->data=i;
r->next=q;
r=q;
}
r->next=NULL;//!!!
}
4)遍歷單鏈表並且求其長度
int GetListLength(List *L){
PtrToLNode ptr;
ptr=(*L)->next;
int length=0;
while(ptr!=NULL){
length++;
printf("%d ",ptr->data);
ptr=ptr->next;
}
printf("\n");
return length;
}
5)在第i個位置前插入新結點
//有頭結點,在第i個位置前插入某個元素,所以i大於等於1小於等於表長
Status ListInsert(List *L,int i,ElementType e){
int j=0;
PtrToLNode t,q;
t=(PtrToLNode)malloc(sizeof(Node));
q=*L;//不是p->(*L)->next;
//q指向第i-1個結點
while(j<i-1&&q){
j++;
q=q->next;
}
if(j>i-1||!q){//如果i<=1,j<i-1;如果i>表長,q=NULL
return ERROR;
}
t->data=e;
t->next=q->next;
q->next=t;
return OK;
}
6)刪除第i個結點
//單鏈表刪除和插入操作都要找第i個位置的前一個結點!
Status ListDelete(List *L,int i,ElementType *e){
int j=0;
PtrToLNode t,q;
t=(PtrToLNode)malloc(sizeof(Node));
q=*L;
while(j<i-1&&q){
j++;
q=q->next;
}
if(j>i-1||!q){
return ERROR;
}
t=q->next;
*e=t->data;
q->next=t->next;
return OK;
}
二、栗子
#include <stdio.h> #include <stdlib.h> #define ERROR -1 #define OK 1 typedef int Status;//函數返回狀態 typedef int ElementType; typedef struct LNode *PtrToLNode;//指向結點的指針 struct LNode{ ElementType data; PtrToLNode next; }; typedef struct LNode Node; typedef PtrToLNode List; void CreateListF(List *L); void CreateListR(List *L); int GetListLength(List *L); Status ListInsert(List *L,int i,ElementType e); Status ListDelete(List *L,int i,ElementType *e); int main() { List L; int length; //初始化 L=(PtrToLNode)malloc(sizeof(Node));//生成頭結點 L->next=NULL; //頭插法 CreateListF(&L); //遍歷單鏈表並且求其長度 printf("頭插法:"); length=GetListLength(&L); printf("長度:%d\n",length); //尾插法 CreateListR(&L); //遍歷單鏈表並且求其長度 printf("尾插法:"); length=GetListLength(&L); printf("長度:%d\n",length); //在第i個位置前插入新結點 int t=ListInsert(&L,1,666); if(t==1){ printf("鏈表長度為:%d\n",GetListLength(&L)); } else if(t==-1){ printf("插入位置越界\n"); } //刪除第i個結點 int e; t=ListDelete(&L,1,&e); if(t==1){ length=GetListLength(&L); printf("長度:%d\n",length); printf("刪除的元素為:%d\n",e); } else if(t==-1){ printf("刪除位置越界\n"); } return 0; } void CreateListF(List *L){ int i; for(i=1;i<=5;i++){ PtrToLNode q; q=(PtrToLNode)malloc(sizeof(Node));//初始化!!! q->data=i; q->next=(*L)->next; (*L)->next=q; } } void CreateListR(List *L){ int i; PtrToLNode r;//尾指針 r=*L; for(i=1;i<=5;i++){ PtrToLNode q; q=(PtrToLNode)malloc(sizeof(Node)); q->data=i; r->next=q; r=q; } r->next=NULL;//!!! } int GetListLength(List *L){ PtrToLNode ptr; ptr=(*L)->next; int length=0; while(ptr!=NULL){ length++; printf("%d ",ptr->data); ptr=ptr->next; } printf("\n"); return length; } //有頭結點,在第i個位置前插入某個元素,所以i大於等於1小於等於表長 Status ListInsert(List *L,int i,ElementType e){ int j=0; PtrToLNode t,q; t=(PtrToLNode)malloc(sizeof(Node)); q=*L;//不是p->(*L)->next; //q指向第i-1個結點 while(j<i-1&&q){ j++; q=q->next; } if(j>i-1||!q){//如果i<=1,j<i-1;如果i>表長,q=NULL return ERROR; } t->data=e; t->next=q->next; q->next=t; return OK; } Status ListDelete(List *L,int i,ElementType *e){ int j=0; PtrToLNode t,q; t=(PtrToLNode)malloc(sizeof(Node)); q=*L; while(j<i-1&&q){ j++; q=q->next; } if(j>i-1||!q){ return ERROR; } t=q->next; *e=t->data; q->next=t->next; return OK; }
三、總結
1)存儲結構:鏈式存儲結構
2)特點:存儲單元不連續
3)存取方式:順序存取
4)有頭結點和無頭結點的操作差異
5)刪除和插入第i個結點,都是要找到第i-1個結點
線性表單鏈表的實現