【資料結構】連結串列操作C實現
阿新 • • 發佈:2018-12-28
資料型別的定義
typedef int DataType;
typedef struct ListNode
{
DataType data;
struct ListNode *next;
} ListNode;
連結串列的初始化和銷燬
連結串列的初始化—–>構造一條空連結串列
連結串列的銷燬—–>銷燬每個結點
//初始化
void ListInit(ListNode **pFirst)
{
*pFirst = NULL;
}
//銷燬
void ListDestory(ListNode **pFirst)
{
ListNode * cur = NULL;
ListNode *del = NULL;
assert(*pFirst);
cur = *pFirst;
while(cur->next != NULL)
{
del = cur;
cur = cur->next;
free(del);
}
free(cur);
}
列印連結串列
void ListPrint(ListNode **pFirst)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst ;
while(cur != NULL)
{
printf("%d ",cur->data);
cur = cur->next;
}
printf("\n");
}
查詢
按值查詢,如果找到了返回第一個找到的結點指標,如果沒找到,返回NULL。程式碼如下:
ListNode *ListFind(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst;
while (cur != NULL)
{
if(cur->data == data)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
增加資料
在增加資料前,需要一個函式來建立一個新結點,函式返回新結點的地址,通過改變連結串列中結點的next指向來將新結點加入到連結串列中。程式碼如下:
ListNode *CreateNode(DataType data)
{
ListNode *NewNode = (ListNode *)malloc(sizeof(DataType));
NewNode->data = data;
NewNode->next = NULL;
return NewNode;
}
尾插
程式碼如下:
void ListPushBack(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
//如果連結串列為空
if(*pFirst == NULL)
{
*pFirst = CreateNode(data);
return ;
}
//連結串列不為空
cur = *pFirst;
while(cur->next != NULL)
{
cur = cur->next;
}
cur->next = CreateNode(data);
}
頭插
程式碼如下:
void ListPushFront(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
//如果連結串列為空
if(*pFirst == NULL)
{
*pFirst = CreateNode(data);
return ;
}
//連結串列不為空
cur = *pFirst;
*pFirst = CreateNode(data);
(*pFirst)->next = cur;
}
指定位置插入(插入到結點前)
程式碼如下:
void ListInsert(ListNode **pFirst, ListNode *pos, DataType data)
{
ListNode *cur = NULL;
ListNode *NewNode = NULL;
assert(*pFirst != NULL);
if(pos == NULL)
return ;
//如果在第一個元素位置前插入,呼叫頭插函式
if(pos == *pFirst)
{
ListPushFront(pFirst, data);
}
cur = *pFirst;
NewNode = CreateNode(data);
while(cur->next != pos)
{
cur = cur->next;
}
cur->next = NewNode;
NewNode->next = pos;
}
刪除資料
尾刪
程式碼如下:
void ListPopBack(ListNode **pFirst)
{
ListNode *cur = NULL;
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果連結串列只有一個元素
if((*pFirst)->next == NULL)
*pFirst = NULL;
//如果連結串列有多個元素
cur = *pFirst;
while(cur->next->next != NULL)
{
cur = cur->next;
}
del = cur->next->next;
cur->next = NULL;
free(del);
}
頭刪
程式碼如下:
void ListPopFront(ListNode **pFirst)
{
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果連結串列只有一個元素
if((*pFirst)->next == NULL)
{
*pFirst = NULL;
}
//如果連結串列有多個元素
del = *pFirst;
*pFirst = (*pFirst)->next;
//free(del);
}
刪除給定結點
程式碼如下:
void ListErase(ListNode **pFirst, ListNode *pos)
{
ListNode *del = NULL;
ListNode *cur = NULL;
assert(*pFirst != NULL);
//如果給定結點不存在
if(pos == NULL)
return ;
//如果給定結點是第一個元素 呼叫頭刪函式
if(pos == *pFirst)
{
ListPopFront(pFirst);
return ;
}
//如果給定結點是最後一個 呼叫尾刪函式
else if(pos->next == NULL)
{
ListPopBack(pFirst);
return ;
}
//如果給定結點是除首尾外元素
cur = *pFirst;
while(cur->next != pos)
{
cur = cur->next;
}
cur->next = cur->next->next;
//free(pos);
}
刪除指定元素
分為兩種情況:
1、如果要刪除元素是第一個元素,就呼叫頭刪函式;
2、如果要刪除元素不是第一個元素,遍歷該連結串列,找到第一個等於要刪除元素的結點,將該結點的前一個結點的next指向該結點的下一個結點,即刪除了該元素。
程式碼如下:
void ListRemove(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
ListNode *del = NULL;
assert(*pFirst != NULL);
//如果刪除的元素為第一個元素
if((*pFirst)->data == data)
{
ListPopFront(pFirst);
return ;
}
cur = *pFirst;
while(cur != NULL)
{
if(cur->next->data == data)
{
del = cur->next;
cur->next = cur->next->next;
return ;
}
cur = cur->next;
}
}
刪除所有指定元素
void ListRemoveAll(ListNode **pFirst, DataType data)
{
ListNode *cur = NULL;
assert(*pFirst != NULL);
cur = *pFirst;
while(cur != NULL)
{
if((*pFirst)->data == data)
{
*pFirst = (*pFirst)->next;
}
else if(cur->next->data == data)
{
cur->next = cur->next->next;
}
cur = cur->next;
}
}
上述內容均為學習過程中的總結,如有不足之處,請指正