資料結構之線性表的鏈式儲存實現(附完整程式碼)
阿新 • • 發佈:2019-02-17
順序表插入、刪除時需要通過移動資料來實現,影響了執行效率。
而連結串列不要求邏輯上相鄰的兩個資料元素物理上也相鄰,因此對線性表的插入、刪除不需要移動資料元素,只需要修改鏈。
下面介紹帶頭結點的鏈式表:
資料結構:
typedef int ElementType;
typedef struct LNode * PtrToLNode;
struct LNode{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;//這裡的位置是結點的地址
typedef PtrToLNode List;
1.初始化:
//初始化 List MakeEmpty(){ List L; L = (List)malloc(sizeof (struct LNode)); if (!L) exit (-1); L->Next = NULL; return L; }
2.求表長
在順序儲存表示的線性表中求表長是一件很容易的事,直接返回Last+1值就可以了,但是在鏈式儲存表示中,需要將連結串列從頭到尾遍歷一遍;設一個移動的指標p和計數器cnt,初始化後,p從表的第一個結點開始往後移,同時計數器cnt+1.
//求表長
int Length(List L){
Position p;
int cnt = 0;
p = L->Next;
while(p){
p = p -> Next;
cnt++;
}
return cnt;
}
3.查詢(按序號查詢FindKth)
對於順序儲存,按序號查詢是很直接的事,要得到第k個元素的值,直接取L->Data[k-1]就可以了。而對於鏈式表就需要採用求表長的思路,從頭遍歷,判斷當前結點是否是第K個,若是,返回該結點的值,否則繼續後一個。
//根據指定的位序查詢s
int FindKth(List L,int K){
Position p;
int cnt = 1;//位序從1開始
p = L->Next;
while(p&&cnt<K){
p = p-> Next;
cnt++;
}
if((cnt==K)&&p) printf("您查詢的數為:%d\n",p -> Data);
else printf("您查詢數不存在");
}
4.查詢(按值查詢Find)
按值查詢的方法也是從頭到尾遍歷,直到找到為止
//按值查詢 Position Find(List L,int X){ Position p; p = L->Next; while(p&&p->Data!=X){ p = p-> Next; } if(p) printf("查詢成功,您查詢的數為:%d\n",p->Data); else printf("您查詢數不存在"); }
5.插入
帶頭結點的鏈式表的插入
//插入
List Insert(List L ,ElementType X,int i){
Position tmp,pre;
int cnt =0 ;
pre = L;
while(pre&&cnt<i-1){
pre = pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1){
printf("插入位置引數錯誤\n");
}
else{
tmp = (Position)malloc(sizeof(struct LNode));
tmp->Data=X;
tmp->Next=pre->Next;
pre->Next=tmp;
}
}
6.刪除
刪除指定位序i的元素,首先需要找到被刪除結點的前一個元素,然後再刪除結點並釋放空間。
//刪除
bool Delete(List L,int i){
Position tmp,pre;
int cnt = 0;
pre = L;
while(pre&&cnt<i-1){
pre=pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1||pre->Next==NULL){
printf("刪除位置引數錯誤");
}
else{
tmp = pre->Next;
pre->Next = tmp->Next;
free(tmp);
printf("刪除成功");
}
}
7.遍歷連結串列並輸出
void DisLinkList(List L)
{
List p = L->Next;
printf("輸出連結串列: ");
while (p)
{
printf("%d ", p->Data);
p = p->Next;
}
}
完整的程式程式碼:
#include<stdio.h>
#include<stdlib.h>
typedef int ElementType;
typedef struct LNode * PtrToLNode;
struct LNode{
ElementType Data;
PtrToLNode Next;
};
typedef PtrToLNode Position;//這裡的位置是結點的地址
typedef PtrToLNode List;
//初始化
List MakeEmpty(){
List L;
L = (List)malloc(sizeof (struct LNode));
if (!L)
exit (-1);
L->Next = NULL;
return L;
}
//根據指定的位序查詢
int FindKth(List L,int K){
Position p;
int cnt = 1;//位序從1開始
p = L->Next;
while(p&&cnt<K){
p = p-> Next;
cnt++;
}
if((cnt==K)&&p) printf("您查詢的數為:%d\n",p -> Data);
else printf("您查詢數不存在");
}
//按值查詢
Position Find(List L,int X){
Position p;
p = L->Next;
while(p&&p->Data!=X){
p = p-> Next;
}
if(p) printf("查詢成功,您查詢的數為:%d\n",p->Data);
else printf("您查詢數不存在");
}
//插入
List Insert(List L ,ElementType X,int i){
Position tmp,pre;
int cnt =0 ;
pre = L;
while(pre&&cnt<i-1){
pre = pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1){
printf("插入位置引數錯誤\n");
}
else{
tmp = (Position)malloc(sizeof(struct LNode));
tmp->Data=X;
tmp->Next=pre->Next;
pre->Next=tmp;
}
}
//刪除
bool Delete(List L,int i){
Position tmp,pre;
int cnt = 0;
pre = L;
while(pre&&cnt<i-1){
pre=pre->Next;
cnt++;
}
if(pre==NULL||cnt!=i-1||pre->Next==NULL){
printf("刪除位置引數錯誤");
}
else{
tmp = pre->Next;
pre->Next = tmp->Next;
free(tmp);
printf("刪除成功");
}
}
//求表長
int Length(List L){
Position p;
int cnt = 0;
p = L->Next;
while(p){
p = p -> Next;
cnt++;
}
return cnt;
}
void DisLinkList(List L)
{
List p = L->Next;
printf("輸出連結串列: ");
while (p)
{
printf("%d ", p->Data);
p = p->Next;
}
}
int main(){
Position pre;
Position L = MakeEmpty();
pre = L;
int i,n,x,len,cz,del;
//插入
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&x);
Insert(pre,x,i);
}
//輸出
DisLinkList(pre);
printf("\n");
//求表長
len = Length(L);
printf("表長為:%d",len);
printf("\n");
//按值查詢
printf("請輸入你要按值查詢的數:\n");
scanf("%d",&cz);
Find(L,cz);
printf("\n");
//按序號查詢
printf("請輸入你要按序號查詢的數的序號:\n");
scanf("%d",&cz);
FindKth(L,cz);
printf("\n");
//刪除
printf("請輸入你要刪除的數的下標:\n",del);
scanf("%d",&del);
Delete(L,del);
DisLinkList(pre);
printf("\n");
return 0;
}