線性表鏈式儲存結構定義:
為了表示每個資料元素ai與其後繼資料元素ai+1之間的邏輯關係,對資料元素ai來說,除了儲存其本身資訊外,還需儲存乙個指示其直接後繼的資訊。我們把儲存資料元素的域稱為資料域,把儲存直接後繼位置的域稱為指標域。指標域中儲存的資訊稱為指標或鏈。這兩部分資訊組成資料元素ai的儲存影像,稱為結點(node)。
n個結點鏈結成乙個鍊錶,即為線性表(a1,a2,……,an)的鏈式儲存結構,因為此鍊錶的每個節點中只包含乙個指標域,所以叫做單鏈表。
我們把鍊錶中第乙個結點的儲存位置叫做頭指標,那麼整個鍊錶的額訪問就必須從頭指標開始進行了。
頭指標和頭節點的異同:
頭指標:
頭指標是指鍊錶指向第乙個結點的指標,若煉表有頭節點,則是指向頭節點的指標。
頭指標具有標識作用,作用常用頭指標冠以鍊錶的名字。
無論鍊錶是否為空,頭指標均不為空。頭指標是鍊錶的必要元素。
頭節點:
頭節點是為了操作的統一和方便而設立的,放在第一元素的結點之前,其資料域一般無意義。
有了頭節點,對在第一元素結點前插入結點和刪除第一結點,其操作和其他結點的操作就統一了。
頭節點不是鍊錶的必須元素。
獲取單鏈表某個元素:
演算法思路:
(1)宣告乙個結點p指向鍊錶的第乙個結點,初始化j從1開始。
(2)當j
(3)若到鍊錶末尾p為空,則說明第i個元素不存在。
(4)否則查詢成功,返回結點p的資料。
單鏈表的插入與刪除:
單鏈表第i個資料插入節點的演算法思路:
(1)宣告乙個結點p指向鍊錶的第乙個結點,初始化j從1開始。
(2)當j
(3)若到鍊錶末尾p為空,則說明第i個元素不存在;
(4)否則查詢成功,在系統中生成乙個空結點s;
(5)將資料元素e賦值給s->data;
(6)單鏈表的插入語句s->next=p->next;p->next=s;
(7)返回成功。
單鏈表第i個資料刪除節點的演算法思路:
(1)宣告乙個結點p指向鍊錶的第乙個結點,初始化j從1開始。
(2)當j
(3)若到鍊錶末尾p為空,則說明第i個元素不存在;
(4)否則查詢成功,將欲刪除的結點p->next賦值給q;
(5)單鏈表的刪除標準語句p->next=q->next;
(6)將q結點中的資料賦值給e,作為返回;
(7)釋放q結點;
(8)返回成功。
單鏈表的整表刪除:
演算法思路:
(1)宣告一結點p和q;
(2)將第乙個結點賦值給p;
(3)迴圈:
將下乙個結點賦值給q;
釋放p;
將q賦值給p.
單鏈表的逆置操作:
演算法思路:
(1)宣告乙個結點p,將第乙個結點賦值給p;
(2)將頭節點的next域置null;
(3)迴圈:
宣告乙個結點q,指向p結點的next;
執行經典插入操作;
q賦值給p。
void reverse(plist plist) //逆置函式
}
先建立標頭檔案:
#pragma once
//帶頭節點的單鏈表
typedef struct node
node,*plist;//plist == node*
void initlist(plist plist);
void insert_head(plist plist,int val); //頭插
void insert_tail(plist plist,int val); //尾插
node *search(plist plist,int key);
bool delete(plist plist,int key);
int getlength(plist plist);
bool isempty(plist plist);
void clear(plist plist);
void destroy(plist plist);
void show(plist plist);
void reverse(plist plist); //鍊錶逆置操作
bool insert_pos(plist plist,int pos,int val); //按位置插入
再實現上述定義的函式:
#include#include#include#include"lianbiao.h"
void initlist(plist plist)
static node *buynode(int val)
void insert_head(plist plist,int val)
void insert_tail(plist plist,int val)
q->next=p;
}node *search(plist plist,int key)
} return null;
}static node *searchprio(plist plist,int key)
} return null;
}bool delete(plist plist,int key)
node *q=searchprio(plist,key);
if(q == null)
q->next=p->next;
free(p);
return true;
}int getlength(plist plist)
return count;
}bool isempty(plist plist)
void clear(plist plist)
void destroy(plist plist) }
void show(plist plist)
printf("\n");
}void reverse(plist plist) //逆置函式
}bool insert_pos(plist plist,int pos,int val) // 1next;
j++;
} if(p == null ||j>pos )
else
}
測試函式**:
/*
* 檔名稱:tasklianbiao.cpp
* 摘要:鍊錶的基本運算
** 當前版本:1.0
* 完成日期:2023年1月25日
* 注:在delete()函式中,與老師的意思有出入。我們可以當前節點,在得到當前的前驅結點,然後進行刪除操作
*/#include#include#include"lianbiao.h"
int main()
show(&head);
int n=getlength(&head); //刪除元素前得到長度
printf("%d \n",n);
delete(&head,3); //刪除某乙個結點
show(&head);
int m=getlength(&head); //刪除元素後得到長度
printf("%d \n",m);
if(isempty(&head)==false) //判空操作
//clear(&head);
int r=getlength(&head); //刪除元素後得到長度
printf("%d \n",r);
if((insert_pos(&head,2,100)) == true)
else
// int r=getlength(&head); //刪除元素後得到長度
printf("%d \n",getlength(&head));
reverse(&head); //逆置測試
show(&head);
//destroy(&head);
return 0;
}
總結完畢,歡迎指正!
資料結構之鍊錶操作
1 基本概念 鏈式儲存結構不需要用位址連續的儲存單元來實現,而是通過 鏈 建立起資料元素之間的順序關係,因此它不要求兩個在邏輯上相鄰的資料元素在物理邏輯上也相鄰。從而,在插入和刪除元素的時候,不需要對原來的資料元素進行移動,只需要改變鍊錶節點之間的指向關係即可,從而提公升了執行時效率。2 主要儲存結...
資料結構之鍊錶操作
面試中單鏈表的相關操作也是常考的內容,本博文也是之前學習時的筆記,在此記錄下來,以便日後用到,同時歡迎批評指正。一 基本操作typedef struct lnode 2.鍊錶的銷毀 void destorylist linklist l else l next ptemp 3.鍊錶的判空 bool ...
資料結構 鍊錶操作之反轉鍊錶
這兩天遇到幾個反轉鍊錶的題目,覺得比較有意思,這裡分享一下 1 給出乙個鍊錶,同時給出索引m和n,要求將位於m和n之間的節點反轉,然後返回結果。1 m n lengthof linklist eg 1 2 3 4 5 m 2,n 4 輸出 1 4 3 2 5 反轉鍊錶的時候,有乙個比較關鍵的技巧,比...