資料結構-C語言單鏈表的實現-尾插尾刪頭插頭刪
阿新 • • 發佈:2021-02-08
單鏈表是一種鏈式存取的資料結構,用一組地址任意的儲存單元存放線性表中的資料元素。連結串列中的資料是以結點來表示的,每個結點的構成:元素(資料元素的映象)
- 指標(指示後繼元素儲存位置),元素就是儲存資料的儲存單元,指標就是連線每個結點的地址資料。
下面程式碼包括尾插尾刪 頭插頭刪 任意位置插入和刪除 查詢 列印 釋放
不囉嗦直接上程式碼
下面是SinList.h
#pragma once
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int SListDataType;
typedef struct SListNode
{
SListDataType data; // 資料域
struct SListNode* next; // 指標域
}SLTNode;
SLTNode* CreatSListNode(SListDataType x); // 建立一個結點
void SListPushBack(SLTNode** pphead, SListDataType x); // 尾插
void SListPopBack(SLTNode** pphead); // 尾刪
void SListPushFront(SLTNode* * pphead, SListDataType x); // 頭插
void SListPopFront(SLTNode** pphead); // 頭刪
void SListInsertAfter(SLTNode** pphead, int pos, SListDataType x); // 在pos位置插入x
void SListEraseAfter(SLTNode** pphead, int pos); // 在pos位置刪除x
SLTNode* SListFind(SLTNode** phead, SListDataType x); // 查詢結點
void SListPrint(SLTNode* phead) ; // 列印連結串列
void FreeList(SLTNode** phead); // 釋放連結串列
下面是SinList.c
#include "SinList.h"
SLTNode* CreatSListNode(SListDataType x)
{
SLTNode* newNode = (SLTNode*)malloc(sizeof(SLTNode));
if (newNode == NULL)
{
printf("申請空間失敗!\n");
exit(-1);
}
newNode->data = x; // 將資料賦給新結點的資料域
newNode->next = NULL; // 下一個結點為NULL
return newNode;
}
void SListPrint(SLTNode* phead)
{
int count = 0;
SLTNode* cur = phead; // 初始化當前值
while (cur != NULL) // 當前值不為空時
{
printf("%d->", cur->data);
cur = cur->next;
count++;
}
printf("NULL\n");
printf("當前結點個數為:%d", count);
}
void SListPushBack(SLTNode** pphead, SListDataType x)
{
SLTNode* newNode = CreatSListNode(x);
if (*pphead == NULL) // 當頭結點為空時直接賦值
*pphead = newNode;
else
{
SLTNode* tail = *pphead;
while (tail->next != NULL) // 找到最後一個結點
{
tail = tail->next;
}
tail->next = newNode; // 將新結點賦給最後一個結點的next
}
}
void SListPopBack(SLTNode** pphead)
{
if (*pphead == NULL) // 如果頭結點為空
exit(-1);
else if ((*pphead)->next == NULL) // 當只有一個結點時
{
free(*pphead);
*pphead = NULL;
}
else // 有多個結點時
{
SLTNode* prev = NULL; // 定義一個跟蹤結點
SLTNode* tail = *pphead;
while (tail->next != NULL) // 找到最後一個結點
{
prev = tail;
tail = tail->next;
}
free(tail); // 釋放最後一個結點
prev->next = NULL; // 將最後一個結點置為NULL
}
}
void SListPushFront(SLTNode** pphead, SListDataType x)
{
SLTNode* newNode = CreatSListNode(x);
newNode->next = *pphead; // 新結點指向頭結點
*pphead = newNode; // 新結點成為頭結點
}
void SListPopFront(SLTNode** pphead)
{
if (*pphead == NULL) // 頭結點為空
exit(-1);
else
{
SLTNode* next = (*pphead)->next;
free(*pphead); // 釋放頭結點
*pphead = next; // 第二個結點為頭指標
}
}
SLTNode* SListFind(SLTNode** pphead, SListDataType x)
{
SLTNode* cur = *pphead;
while(cur) // 當前結點不為空時
{
if (cur->data == x) // 查詢匹配項
return cur;
cur = cur->next;
}
return NULL;
}
void SListInsertAfter(SLTNode** pphead, int pos, SListDataType x)
{
if (*pphead == NULL)
exit(-1);
SLTNode* cur = *pphead;
SLTNode* newnode = CreatSListNode(x);
int curpos = 1; // 當前位置
while (cur->next != NULL && curpos < pos - 1) // 迴圈找到對應位置的前一個結點
{
cur = cur->next;
curpos++;
}
newnode->next = cur->next; // 新結點指向插入位置的後一個結點
cur->next = newnode; // 前一個結點指向新結點
}
void SListEraseAfter(SLTNode** pphead, int pos)
{
if (*pphead == NULL)
exit(-1);
if (pos == 1) // 刪除第一個結點
*pphead = (*pphead)->next;
else
{
int curpos = 1; // 當前位置
SLTNode* prev = NULL; // 用於定位刪除位置的前一個結點
SLTNode* cur = *pphead;
while (cur->next != NULL && curpos < pos) // 迴圈找到對應刪除位置結點
{
prev = cur;
cur = cur->next;
curpos++;
}
prev->next = cur->next; // 刪除位置前的結點指向要刪除位置結點的後一個結點
free(cur); // 釋放刪除結點
}
}
void FreeList(SLTNode** phead)
{
SLTNode* current = *phead;
while (*phead != NULL)
{
*phead = current->next;
free(current);
current = *phead;
}
}
int main()
{
SLTNode* L = NULL;
SListPushBack(&L, 1);
SListPushBack(&L, 2);
SListPushBack(&L, 3);
SListPushBack(&L, 4);
SListPopBack(&L);
SListPushFront(&L, 6);
SListInsertAfter(&L, 7, 4);
SListEraseAfter(&L, 1);
SLTNode* ret = SListFind(&L, 7);
if (ret)
printf("%d存在\n", ret->data);
else
printf("不存在\n");
SListPrint(L);
FreeList(&L);
}
下面是程式碼執行圖