在(1)的基礎上增加插入和刪除的函數
插入原理:將新的節點的指針域指向插入空的下一個節點,空的上一個節點的指針域指向這個新的節點
刪除原理:要增加一個新的節點才能使刪除成立,首先讓新的節點指向下一個節點,然後刪除要刪除的節點,再讓上一個節點指向下一個節點,再刪除掉新建立的節點,保證輸出節點佔用的內存被釋放掉。
貼出代碼:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node{
int data;//數據域,這裏存放的是想要存儲的數據
struct Node * pNext;//指針域,這裏的存放的是下一個節點的地址
}NODE, *PNODE;//用typedef函數,就是type的define,使得NODE等價於struct Node,PNODE等價於struct Node *
//聲明函數
PNODE create_list();//鏈表創建的函數,用於創建一個非循環單鏈表
int traverse_list(PNODE);//用於輸出鏈表
bool insert_list(PNODE, int, int);//用於插入
bool delete_list(PNODE, int);//用於刪除
int main(){
PNODE pHead = NULL;//等價於 struct Node * pHead = NULL;
pHead = create_list();//create_list()功能:創建一個非循環單鏈表,並將該鏈表的頭結點的地址賦給pHead
insert_list(pHead, 3, 10);//插入函數使用,在第三個位置插入一個10
traverse_list(pHead);//鏈表中數據一個一個輸出
delete_list(pHead, 4);//刪除函數使用,刪除第四個節點
traverse_list(pHead);//鏈表中數據一個一個輸出
return 0;
}
PNODE create_list(){
int len;//用來存放有效節點的個數
int i;
int val;//用來臨時存放用戶輸入的結點的值
PNODE pHead = (PNODE)malloc(sizeof(NODE));//分配了一個不存放有效數據的頭結點
if (NULL == pHead){//這裏的寫法是一種安全的做法,如果不小心把==寫成了=,NULL=pHead是會報錯的,而pHead=NULL就會當做賦值然後返回true處理
printf("分配失敗, 程序終止\n");
exit(-1);
}
/*
這裏設定pTail的原因是:
鏈表的操作原理是將新的節點掛在尾節點上
而尾節點沒有辦法表達出來
所以增加一個pTail來作爲尾節點
方便下面的pNew掛上去
*/
PNODE pTail = pHead;
pTail->pNext = NULL;
printf("請輸入您需要生成的鏈表節點的個數: len = ");
scanf("%d", &len);
for (i=0; i<len; ++i){
printf("請輸入第%d個節點的值: ", i+1);
scanf("%d", &val);
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if (NULL == pNew){
printf("分配失敗, 程序終止\n");
exit(-1);
}
/*
第一句pNew->data = val;可以放在下面四個語句的任意位置
第二句是將pNew掛在尾節點上
第三句是將pNew的指針域設定爲空,意思是這是新的尾節點
第四句是將pTail變成新的尾節點,使得循環操作成立
*/
pNew->data = val;
pTail->pNext = pNew;
pNew->pNext = NULL;
pTail = pNew;
}
return pHead;
}
int traverse_list(PNODE pHead){
//定義一個指針,從首節點開始
PNODE p = pHead->pNext;
//判定,若p不爲NULL,輸出p所對應節點的數據,然後指針移向下一個節點
while (NULL != p){
printf("%-5d", p->data);
p = p->pNext;
}
printf("\n");
return 0;
}
//insert_list函數的目的:在鏈表的第pos個節點前面增加一個節點,其數據域爲val
bool insert_list(PNODE pHead, int pos, int val){
int i = 0;
PNODE p = pHead;
//將指針p移動到要插入的位置
while(NULL!=p && i<pos-1){
p = p->pNext;
i++;
}
if(i>pos-1 || NULL==p)
return false;
//建立要插入的節點
PNODE pNew = (PNODE)malloc(sizeof(NODE));
if(NULL == pNew){
printf("分配內存失敗\n");
exit(-1);
}
pNew->data = val;
PNODE q = p->pNext;
p->pNext = pNew;
pNew->pNext = q;
return true;
}
bool delete_list(PNODE pHead, int pos){
int i = 0;
PNODE p = pHead;
//將指針指向要刪除的節點
while(NULL!=p->pNext && i<pos-1){
p = p->pNext;
i++;
}
if(i>pos-1 || NULL==p->pNext)
return false;
PNODE q = p->pNext;
p->pNext = p->pNext->pNext;
free(q);//釋放q指向的空間
q = NULL;//再“釋放”掉指針q
return true;
}
這裏再說一下free(q)再q=NULL的必要性
free是釋放掉q指向的空間,而q還是指向那個空間的,要把q也釋放掉,就需要再將q賦值一個NULL使得p指向0。