用c語言實現資料結構——單連結串列
單連結串列
用通俗的語言來說,單連結串列就像是頭和尾沒有連線起來的自行車鏈,每一個節點都是獨立的,卻又相互聯絡。特點:地址不連續,但是又相互有聯絡。
建立連結串列
1.頭插法:
(1)為了操作方便,一般情況下,連結串列的頭節點是不存放資料的。
(2)如果輸入1 2 3 4,那麼輸出是 4 3 2 1,是相反的。從這裡我們就有了頭插法的思路,首先讓頭節點(head)和第一個新的節點連線(temp1)。之後的新節點(temp2)要插入到第一個新節點(temp1)的前面。在圖中的表現如下:
第一步:讓頭指標和第一個temp連線起來:
第二步:第二個temp連線到第一個temp的前面:
第三步:頭節點和第二個temp連線(頭連temp):
最後一步就是頭節點和第一個temp斷開:
後續就以此類推了。
程式碼如下:
temp->next = head->next;
head->next = temp;
2.尾插法:
(1)頭節點依舊不存放資料
(2)如果輸入 1 2 3 4,那麼就輸出 1 2 3 4,思路:需要一個節點指標tail,可以理解為遊標,防止頭指標丟失的。一開始只有一個節點的時候,連結串列的頭和尾是一樣的。所以一開始會有tail=head。
第一步:頭和尾指向同一個位置:
第二步:尾和新節點temp連線:
第三步:新節點temp成為新的尾巴:
後續就以此類推了
程式碼如下:
tail->next = temp;/*先連線兩個節點*/
tail = tail->next;/*尾指標後移*/
當你能看懂建立連結串列的時候,後面的基本操作基本也都會了,要說的也就是刪除這裡了。
刪除對應位置節點
原理:找到要刪除的位置的節點的前一個節點,然後讓刪除位置前一個節點的next指標指向它的下下個節點,接著釋放掉刪除位置的節點。這就完成了刪除操作。
圖解:
假如我要刪除第2個節點,那麼我就要用一個指標遍歷到第1個節點:
這個時候節點1和節點3直接連線起來:
最後釋放掉節點2,這就相當於本來你和你女朋友拉著手呢,結果來了另一個比你帥比你有錢的男孩,拉走了你的女朋友,然後你被拋棄了哈哈哈。
程式碼如下:
/*
Function name :deleteNode
Description : 指定位置刪除節點
Parameter :
@head : 單連結串列的頭指標
@i : 要刪除的位置
return : 返回1成功,返回其他失敗
*/
int deleteNode(Node *head, int i)
{
Node *temp = head;/*防止頭指標丟失*/
int num = getNum(head);/*獲取連結串列長度*/
if (i<1 || i>num) return 0;/*刪除位置不合法*/
for (int k = 0; k < i - 1; k++)/*temp指標移到要刪除的節點前*/
{
temp = temp->next;
}
Node *willDelete = temp->next;/*要刪除的節點*/
temp->next = willDelete->next;/*隔著要刪除的節點連線*/
free(willDelete);/*釋放要刪除的節點*/
return 1;
}
完整程式碼,註釋和執行結果
講在前面,如果你瞭解單連結串列的基本原理,那麼這個程式碼看起來會很輕鬆。
/*********************************************
@File name : singleChainList.c
@Author : StudyCcYa
@Version : 1.0
@Date : 2020-11-08
@Description : 用c語言實現資料結構——單連結串列
********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef int Type;
/*單連結串列節點的結構體*/
typedef struct Node
{
Type data;/*單連結串列的資料*/
struct Node *next;/*用於指向下一個節點的結構體指標*/
}Node;
Node *initNode();/*初始化單連結串列節點*/
Node *emptyNode();/*建立一個空的節點*/
Node *creatListHead();/*頭插法建立一個單連結串列*/
Node *creatListTail();/*尾插法建立一個單連結串列*/
int printList(Node *head);/*輸出單連結串列中的所有節點*/
int getNum(Node *head);/*統計節點個數*/
int insertElem(Node *head, int i,Type elem);/*指定位置增加(插入)資料*/
int deleteNode(Node *head, int i);/*指定位置刪除節點*/
Type getNode(Node *head, int i);/*查詢指定位置的資料*/
int changeNode(Node *head, int i,Type elem);/*修改指定位置的資料*/
/*
Function name : initNode
Description : 初始化單連結串列節點
Parameter :
無
return : 返回一個單連結串列節點,否則失敗
*/
Node *initNode()
{
Node *temp = (Node *)malloc(sizeof(Node));/*申請一個節點的空間*/
assert(temp);/*斷言,如果申請空間失敗則報錯*/
temp->data = 0;
temp->next = NULL;
return temp;
}
/*
Function name : emptyNode
Description : 建立一個空的節點
Parameter :
無
return : 返回一個空的單連結串列節點,否則失敗
*/
Node *emptyNode()
{
Node *temp = (Node *)malloc(sizeof(Node));/*申請一個節點的空間*/
assert(temp);
temp->next = NULL;
return temp;
}
/*
Function name : creatList
Description : 頭插法建立一個單連結串列
Parameter :
無
return : 返回一個單連結串列的頭指標,其他失敗
*/
Node *creatListHead()
{
int n;
Type elem;
Node *head = emptyNode();/*頭指標不存放資料*/
printf("請輸入要建立連結串列節點的數量(頭插):\n");
scanf("%d",&n);
printf("請輸入資料:\n");
for (int i = 0; i < n; i++)
{
Node *temp = initNode();
scanf("%d",&temp->data);
temp->next = head->next;/*新節點的next指標和頭節點的next的指標指向同一位置*/
head->next = temp;/*連線*/
}
return head;
}
/*
Function name : creatListTail
Description : 尾插法建立單連結串列
Parameter :
@head : 單連結串列的頭指標
return : 返回一個頭指標,返回其他失敗
*/
Node *creatListTail()
{
Node *head = emptyNode();/*頭指標不存放資料*/
Node *tail = head;/*一開始頭尾指向位置一樣*/
int n;
printf("請輸入要建立連結串列節點的數量(尾插):\n");
scanf("%d", &n);
printf("請輸入資料:\n");
for (int i = 0; i < n; i++)
{
Node *temp = initNode();
scanf("%d", &temp->data);
tail->next = temp;/*先連線兩個節點*/
tail = tail->next;/*尾指標後移*/
}
return head;
}
/*
Function name : printList
Description : 輸出單連結串列
Parameter :
@head : 單連結串列的頭指標
return : 返回1成功,返回其他失敗
*/
int printList(Node *head)
{
Node *temp = head->next;/*臨時連結串列指標,防止頭指標丟失*/
for (; temp != NULL; temp = temp->next)/*迴圈遍歷連結串列*/
{
if (temp->next != NULL)/*沒有到最後一個節點*/
{
printf("%d->", temp->data);
}
if (temp->next == NULL)/*到最後一個節點*/
{
printf("%d\n",temp->data);
return 1;/*輸出成功*/
}
}
return 0;
}
/*
Function name : getNum
Description : 統計節點個數
Parameter :
@head : 單連結串列的頭指標
return : 返回單連結串列節點的個數,返回其他失敗
*/
int getNum(Node *head)
{
int i = 0;/*用於計數*/
Node *temp = head->next;/*第一個節點不算*/
while (temp!=NULL)
{
i++;
temp = temp->next;
}
return i;
}
/*
Function name :insertElem
Description : 指定位置增加(插入)資料
Parameter :
@head: 單連結串列的頭指標
@i : 插入的位置
@elem: 插入的資料
return : 返回1成功,其他失敗
*/
int insertElem(Node *head, int i,Type elem)
{
Node *temp = head;
int num = getNum(head);/*獲取單連結串列的長度*/
if (i<1 || i>num+1) return 0;/*插入位置不合法*/
//if (i == 1) /*如果在最前面插入*/
//{
// Node *newNode = initNode();
// newNode->data = elem;//賦值
// newNode->next = temp->next;/*這裡相當於一個頭插*/
// temp->next = newNode;
// return 1;
//}
//if (i >= 1 && i <= num)/*如果在中間插入*/
//{
for (int k = 0; k < i-1; k++)/*temp指標移到要插入的節點前,這個時候就體現出頭節點不儲存資料的好處了*/
{
temp = temp->next;
}
/*下面的程式碼段就跟上面一樣了*/
Node *newNode = initNode();
newNode->data = elem;
newNode->next = temp->next;
temp->next = newNode;
return 1;
//}
return 0; /*表示插入失敗咯*/
/*插到最後的情況是跟中間一樣的。所以不再做處理*/
}
/*
Function name :deleteNode
Description : 指定位置刪除節點
Parameter :
@head : 單連結串列的頭指標
@i : 要刪除的位置
return : 返回1成功,返回其他失敗
*/
int deleteNode(Node *head, int i)
{
Node *temp = head;/*防止頭指標丟失*/
int num = getNum(head);/*獲取連結串列長度*/
if (i<1 || i>num) return 0;/*刪除位置不合法*/
for (int k = 0; k < i - 1; k++)/*temp指標移到要刪除的節點前*/
{
temp = temp->next;
}
Node *willDelete = temp->next;/*要刪除的節點*/
temp->next = willDelete->next;/*隔著要刪除的節點連線*/
free(willDelete);/*釋放要刪除的節點*/
return 1;
}
/*
Function name : getNode
Description : 查詢指定位置的資料
Parameter :
@head : 單連結串列的頭指標
@i : 要查詢的位置
return : 返回1成功,返回其他失敗
*/
Type getNode(Node *head, int i)
{
Node *temp = head;/*防止頭指標丟失*/
int num = getNum(head);/*獲取單連結串列長度*/
if (i<1 || i>num) return 0;/*查詢位置不合法*/
for (int k = 0; k < i; k++)/*temp指標移動到要查詢的節點*/
{
temp = temp->next;
}
return temp->data;/*將資料返回到函式*/
}
/*
Function name : changeNode
Description : 修改指定位置的資料
Parameter :
@head : 單連結串列的頭指標
@i : 修改的位置
@elem : 替換的資料
return : 返回1成功,其他失敗
*/
int changeNode(Node *head, int i, Type elem)
{
Node *temp = head;/*防止頭指標丟失*/
int num = getNum(head);/*獲取單連結串列長度*/
if (i<1 || i>num) return 0;/*修改位置不合法*/
for (int k = 0; k < i; k++)/*temp指標移動到要修改的節點*/
{
temp = temp->next;
}
temp->data = elem;/*替換資料*/
return 1;
}
int main()
{
Node *head = creatListHead();/*頭插法*/
printList(head);/*輸出頭插連結串列*/
Node *head1 = creatListTail();/*尾插法*/
printList(head1);/*輸出尾插連結串列*/
printf("增:\n");
insertElem(head, 1, 66);/*第1個位置插入66*/
printList(head);
insertElem(head, 3, 77);/*中間位置插入77*/
printList(head);
insertElem(head, 8, 99);/*最後位置插入99*/
printList(head);
printf("刪:\n");
deleteNode(head, 1);/*刪除第一個節點*/
printList(head);
deleteNode(head, 3);/*刪除中間節點*/
printList(head);
deleteNode(head, 6);/*刪除最後節點*/
printList(head);
printf("查:\n");
printf("1:%d\n", getNode(head, 1));/*查詢第1個節點的資料*/
printf("2:%d\n", getNode(head, 2));/*查詢中間節點的資料*/
printf("5:%d\n", getNode(head, 5));/*查詢最後節點的資料*/
printf("改:\n");
changeNode(head, 1, 22);/*第1個節點資料改成22*/
printList(head);
changeNode(head, 3, 33);/*中間節點資料改成33*/
printList(head);
changeNode(head, 5, 44);/*最後節點資料改成44*/
printList(head);
return 0;
}
執行成功。
如有不足和建議,歡迎指正和討論。後續會將所有的資料結構用c語言和java語言實現。
相關文章
- 資料結構——單連結串列介面實現(C語言)資料結構C語言
- 【資料結構】用C語言實現單連結串列及其常見操作資料結構C語言
- 資料結構_連結串列的原理與應用1_單連結串列(基於C語言實現)資料結構C語言
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 資料結構——單連結串列的C++實現資料結構C++
- “c語言+結構體+連結串列”實現名片系統C語言結構體
- js實現資料結構--單連結串列JS資料結構
- 基數排序-單連結串列實現【資料結構與演算法分析(c 語言描述)】排序資料結構演算法
- 資料結構__連結串列_單連結串列的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- 【資料結構】連結串列(單連結串列實現+詳解+原碼)資料結構
- c語言單向連結串列逆轉實現方法C語言
- C語言資料結構:單向迴圈連結串列的增刪操作C語言資料結構
- 資料結構與演算法分析(c 語言描述)多項式 ADT 單連結串列實現資料結構演算法
- 資料結構-單連結串列、雙連結串列資料結構
- 資料結構_連結串列_單向迴圈連結串列 & 雙向連結串列的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- 資料結構筆試題——基於C語言的連結串列功能函式實現資料結構筆試C語言函式
- C語言資料結構:雙向連結串列的增刪操作C語言資料結構
- 資料結構之php實現單向連結串列資料結構PHP
- 資料結構_連結串列_單向迴圈連結串列的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- 資料結構-2.單向連結串列的實現資料結構
- 資料結構--單連結串列(通過陣列實現)資料結構陣列
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 連結串列-單連結串列實現
- 資料結構之單連結串列資料結構
- 資料結構04——單連結串列資料結構
- 資料結構和演算法——Go實現單連結串列並且反轉單連結串列資料結構演算法Go
- Go 語言 結構體連結串列Go結構體
- C語言資料結構:雙向迴圈連結串列的增刪操作C語言資料結構
- 6-C/C++實現資料結構連結串列相關操作C++資料結構
- 單向連結串列————遍歷、查詢、插入結點 (基於C語言實現)C語言
- 演算法與資料結構-連結串列((linked-list)-Java實現單向連結串列演算法資料結構Java
- 資料結構_連結串列_雙向迴圈連結串列的初始化、插入、刪除、修改、查詢列印(基於C語言實現)資料結構C語言
- C語言線性連結串列C語言
- 資料結構實驗:連結串列的應用資料結構
- 資料結構(雙向連結串列的實現)資料結構
- 資料結構-雙向連結串列(Python實現)資料結構Python
- php實現基本資料結構之連結串列PHP資料結構
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列