重慶分公司,新征程啟航
為企業提供網站建設、域名注冊、服務器等服務
為企業提供網站建設、域名注冊、服務器等服務
/*
創新互聯主要業務有網站營銷策劃、成都做網站、成都網站建設、微信公眾號開發、微信小程序開發、H5建站、程序開發等業務。一次合作終身朋友,是我們奉行的宗旨;我們不僅僅把客戶當客戶,還把客戶視為我們的合作伙伴,在開展業務的過程中,公司還積累了豐富的行業經驗、全網整合營銷推廣資源和合作伙伴關系資源,并逐漸建立起規范的客戶服務和保障體系。
鏈表節點的插入與刪除
編譯環境:VC++?6.0
編譯系統:windows?XP?SP3
*/
#include?stdio.h
#include?stdlib.h
#include?malloc.h
//????定義鏈表中的節點
typedef?struct?node
{
int?member;????????????????//????節點中的成員
struct?node?*pNext;????????//????指向下一個節點的指針
}Node,*pNode;
//????函數聲明
pNode?CreateList();?????????????????//??創建鏈表函數
void?TraverseList(pNode?);????????????//??遍歷鏈表函數
bool?Insert_Node(pNode?,int?,int);????//????鏈表節點插入函數,第一個參數是頭節點,第二個參數是要在第幾個節點前插入,第三個參數是要插入的數據
int?Del_Node(pNode,int?);????????//????刪除鏈表節點,第一個參數是頭節點,第二個參數是刪除第幾個節點,第三個作為
int?main()
{
pNode?pHead?=?NULL;????????????????//??定義初始化頭節點,等價于?struct?Node?*pHead?==?NULL
int?data;????????????????????????//?作為Insert_Node函數的第三個參數
int?num;????????????????????????//????作為Inset_Node函數第二個參數
int?choose;
int?return_val;
pHead?=?CreateList();????????????//??創建一個非循環單鏈表,并將該鏈表的頭結點的地址付給pHead
printf("你輸入的數據是:");
TraverseList(pHead);????//??調用遍歷鏈表函數
printf("是否還要進行如下操作:\n");
printf("1.插入數據??????2.刪除數據\n");
printf("請輸入:");
scanf("%d",choose);
switch?(choose)
{
case?1:
{
printf("請輸入要在第幾個節點前插入數據:");
scanf("%d",num);
printf("請輸入要插入的數據:");
scanf("%d",data);
if(Insert_Node(pHead,num,data)?==?true)
{
printf("插入成功\n插入后的數據是:\n");
TraverseList(pHead);
}
else
{
printf("插入失敗\n");
}
printf("操作完成后的數據是:");
TraverseList(pHead);
break;
}
case?2:
{
printf("請輸入要刪除第幾個節點的數據:");
scanf("%d",num);
return_val?=?Del_Node(pHead,num);
if?(return_val?==?0)
{
printf("刪除失敗。\n");
}
else
{
printf("刪除成功。刪除的元素是:%d\n",return_val);
}
printf("操作完成后的數據是:");
TraverseList(pHead);
}
}
return?0;
}
//????創建鏈表函數
pNode?CreateList()
{
int?i;????????????????????????????????????????????//????用于下面循環
int?len;????????????????????????????????????????//????用來存放有效節點的字數
int?val;????????????????????????????????????????//????用于臨時存放用戶輸入的數據
pNode?pHead?=?(pNode)malloc(sizeof(Node));????????//??分配一個不存放有效數據的頭結點
pNode?pTail?=?pHead;????????????????????????????//????鏈表的最后一個節點
pTail-pNext?=?NULL;????????????????????????????//????最后一個節點的指針置為空
printf("請輸入節點個數:");
scanf("%d",len);
for(i?=?0;?i??len;?i++)
{
printf("第?%d?個節點的數值:",i+1);
scanf("%d",val);
pNode?pNew?=?(pNode)malloc(sizeof(Node));????//????為節點分配空間
pNew-member?=?val;????????????????????????????//將用戶輸入的數據賦給節點的成員
pTail-pNext?=?pNew;????????????????????????//將最后一個節點的指針指向下一個新的節點
pNew-pNext?=?NULL;????????????????????????????//將新節點中的指針置為空
pTail?=?pNew;????????????????????????????????//將新節點賦給最后的一個節點
}
return?pHead;????????????????????????????????????//返回頭節點
}
//????遍歷鏈表函數
void?TraverseList(pNode?pHead)
{
pNode?p?=?pHead-pNext;????????????????????????????//將頭節點的指針給予臨時節點p
while(NULL?!=?p)????????????????????????????????//節點p不為空,循環
{
printf("%d?",p-member);
p?=?p-pNext;
}
printf("\n");
return?;
}
//????鏈表節點插入函數
//????第一個參數是頭節點,第二個參數是要在第幾個節點前插入,第三個參數是要插入的數據
bool?Insert_Node(pNode?pHead,?int?front,int?data)
{
int?i?=?0;
pNode?_node?=?pHead;
pNode?pSwap;????????????????????????????????//????用于交換
if?((front??1)??(NULL?!=?_node))????????//判斷用戶輸入的數據是否大于等于1,及_node是否為空
{
return?false;
}
while?(i??front?-?1)????????????????????//通過循環使指針指向要插入哪個節點前的節點。說的自己都不懂了,還是看下面的圖吧。
{
_node?=?_node-pNext;
++i;
}
pNode?pNew?=?(pNode)malloc(sizeof(Node));
pNew-member?=?data;????????????????????????//????把輸入的數據賦給要插入的節點
pSwap?=?_node-pNext;????????????????????????//????把下一個節點的地址,給用于交換的pSwap
_node-pNext?=?pNew;????????????????????????//????把要插入的節點的地址,給上個節點的指針域
pNew-pNext?=?pSwap;????????????????????????//????把插入節點的下一個節點的地址,給插入節點的指針域
return?true;
}
//????刪除鏈表節點函數
//????第一個參數是頭節點,第二個參數是要刪除第幾個節點·······和上面的插入函數是不是很像
int?Del_Node(pNode?pHead,int?back)
{
int?i?=?0;
int?data;
pNode?_node?=?pHead;
pNode?pSwap;
if?((back??1)??(NULL?==?_node-pNext))
{
printf("刪除失敗!\n");
return?0;
}
while(i??back-1)
{
_node?=?_node-pNext;
++i;
}
pSwap?=?_node-pNext;
data?=?pSwap-member;
_node-pNext?=?_node-pNext-pNext;
free(pSwap);
return?data;
}
我自己也畫了兩張圖片,幫助理解,反正我是這么理解的,有錯的歡迎指出
先看下向鏈表中插入節點
下面這個是刪除鏈表節點
用兩個指針,p,qp指向該結點的前驅,p指向該結點,然后 p-next=q-next;就刪除成功了~~
struct?node?*delete(struct?node*?head)//刪除函數
{
printf("請輸入要刪除的學生姓名");
char?k[100];
scanf("%s",?k);
struct?node?*pre?=?NULL;
struct?node?*q???=?head;
while?(q)?{
if?(strcmp(q-data.name,?k)?==?0){
if?(pre)
pre-next?=?q-next;
else?
head?=?q-next;
free(q);
break;
}
pre?=?q;
q?=?q-next;
}
return?head;
}
剛學C語言呢,就是看不出來這個問題,其實問題很簡單,就是你在C語言的函數里面傳入了一個值,是的它是一個值,你看到的你傳了一個指針進去,其實這個指針本身也是一個值,鏈表的頭結點是個指針,你要改變這個指針就要用指針的指針才能改變,指針變量也是一個變量,你傳入一個指針他也只是在函數的作用域里面過了一份拷貝!看程序!
/*你想改變a的值,所以你傳了一個指針進去*/
void?change(int?*a)
{
*a?=?10;
}
int?main()
{
int?a?=?0;
change(a);
}
這里要說的是其實,指針也是一個變量;所以你想改變一個指針的值,同樣的你也要把這個指針的地址傳進去,就是指針的指針了,看代碼!
void?changePtr(int*?*a)
{
*a?=?(int*)malloc(sizeof(int));
}
int?main()
{
int?a?=?10,*p?=?a;
changePtr(p);
}
上面的兩個代碼我也沒測!就是舉個例子!
看下面的代碼!就是你這個鏈表的!或者直接打開下面網址(包含下面代碼輸出結果)
#define?size?5
#define?del1?"one"
#define?del5?"five"
#define?del?"none"
#define?del3?"three"
typedef?struct?VIDEO?{
char?name[20];
struct?VIDEO?*next;
}?video;
/*video?*head;*/
void?build(video**head)?{
int?i?=?0;
video?*temp;
char?*ss[5]?=?{"one","two","three","four","five"};
temp?=?*head?=?NULL;
for(i?=?0;i??size;i++)?{
if(*head)?{
temp-next?=?(video*)malloc(sizeof(video));
temp?=?temp-next;
/*scanf("%s",temp-name);*/
strcpy(temp-name,ss[i]);
temp-next?=?NULL;
}?else?{
*head?=?(video*)malloc(sizeof(video));
/*scanf("%s",head-name);*/
strcpy((*head)-name,ss[i]);
(*head)-next?=?NULL;
temp?=?*head;
}
}
}
int?delete(video**head,char?*str)?{
video?*cur,*prv?=?*head;
if(*head?==?NULL)?return?0;
if(strcmp((*head)-name,str)?==?0)?{
*head?=?(*head)-next;
free(prv);
return?1;
}
cur?=?prv-next;
while(cur??strcmp(cur,str))?{
cur?=?cur-next;
prv?=?prv-next;
}
if(cur)?{
prv-next?=?cur-next;
free(cur);
return?1;
}?else?{
return?0;
}
}
void?show(video?*head)?{
if(head)?{
printf("%s",head-name);
while(head-next)?{
head?=?head-next;
printf("-%s",head-name);
}
printf("\n");
}
}
int?main()
{
video?*head;
build(head);
show(head);
delete(head,del1);
show(head);
delete(head,del5);
show(head);
delete(head,del);
show(head);
delete(head,del3);
show(head);
return?0;
}
輸出結果為:
one-two-three-four-five
two-three-four-five
two-three-four
two-three-four
two-four
p1 = head;
p = head-next;
while(p-next != NULL)//當鏈表下個節點不是末尾時
{
if((p-number mink)||(p-number maxk))//如果節點值不滿足條件,則刪除該節點
{
p = p-next;
p1-next = p;
}
else //尋找下一個節點
{
p =p-next;
p1 = p1-next;
}
}
額。。
反正要刪除要兩個指針
1、P1一個指向要刪除的上一個節點,P2一個指向要刪除節點
2、把P1指向P2的next-
3、釋放沒用的空間