❶ 關於c語言中的雙向鏈表中的刪除和插入問題
我想問的是p->rlink指的是p右邊的結點嗎還是p所指向的結點的右指針域?
——p->rlink的內容,是p的右邊節點的地址;
p->llink->rlink指的是p左邊結點的右指針域嗎還是p左邊結點的後繼結點(可後繼結點不是p嗎,這句賦值語句是什麼意思呢?)?
——p的左節點的rlink的值,當前是p的地址,這句代碼是將rlink的值修改為p->rlink,即p的右節點;
其中p->llink->rlink->llink=p->llink這句是什麼意思呢?我的理解是:把p所指向的結點的
前驅結點的地址賦給(p所指向的結點的前驅結點的後驅結點(這個後驅結點是p嗎?)的左指針域),對嗎?
——p的右節點的llink內容的值填充喂p的左邊節點。
看下面圖是否更清晰:
❷ 雙向鏈表的創建C++中如何編寫一個程序實現雙向鏈表的建立,插入和刪除
//CreateList_L.cpp
//To create a LinkList
#include <stdlib.h>
#include <iostream.h>
#include <conio.h>
# define TRUE 1
# define FALSE 0
# define OK 1
# define ERROR 0
# define INFEASIBLE -1
# define OVERFLOW -2
typedef struct DuLNode
{ int data;
struct DuLNode *prior;
struct DuLNode *next;
}DuLNode,*DuLinkList;
// 初始條件:L已存在。操作結果:返回L中數據元素個數
int ListLength(DuLinkList L)
{
int i=0;
DuLinkList p=L->next; // p指向第一個結點
while(p!=L) // p沒到表頭
{
i++;
p=p->next;
}
return i;
}
// 由雙鏈循環線性表L的頭結點出發,正序輸出每個數據元素
void ListTraverse(DuLinkList L)
{
DuLinkList p=L->next;
while(p!=L)
{
cout<<p->data<<"\t";
p=p->next;
}
cout<<endl;
}
// 由雙鏈循環線性表L的頭結點出發,逆序輸出每個數據元素
void ListTraverseBack(DuLinkList L)
{
DuLinkList p=L->prior;
while(p!=L)
{
cout<<p->data<<"\t";
p=p->prior;
}
cout<<endl;
}
//To Creatre a DuLinkList L with HeadNode
void CreateList_DuL(DuLinkList &L)
{
int n;
int i;
DuLNode *p;
L=(DuLinkList)malloc(sizeof(DuLNode));
L->next=L->prior=L;
cout<<"CreateList_L"<<endl<<"================"<<endl;
cout<<"Please input the Init DuLinkNode Number: <eg. 5> ";
cin>>n;
cout<<"Please input the data for DuLinkList Nodes: <eg. 34,67,3,-9,45,...>"<<endl;
for(i=n;i>0;--i)
{
p=(DuLinkList)malloc(sizeof(DuLNode));
cin>>p->data; //Reverse order inputing for Creating a LinkList
p->prior=L;
p->next=L->next;
L->next->prior=p;
L->next=p;
}
if(n)
{
cout<<endl;
cout<<"Success to Create a DuLinkList !"<<endl;
ListTraverse(L);
cout<<endl;
}
else cout<<"A NULL DuLinkList have been created !"<<endl;
}
//ListInsert_Dul()
int ListInsert_DuL(DuLinkList &L)
{
DuLNode *p=L,*s;
int j=0;
int i;
int e;
cout<<"======"<<"before insert:"<<"======"<<endl;
ListTraverse(L);
cout<<"input the location you want to insert:";
cin>>i;
while (i<1||i>ListLength(L)+1)
{
//i值不合法
cout<<"illeagle location,please input the correct location:";
cin>>i;
}
cout<<"input the number you want to insert:";
cin>>e;
while(j<i)
{ p=p->next;
++j;
}
if(!(s=(DuLinkList)malloc(sizeof(DuLNode))))
{
cout<<endl<<"Allocate space failure ! " ;
return (ERROR);
}
s->data=e;
s->prior=p->prior;
s->next=p;
if(i==1)
L->next=s;
p->prior->next=s;
p->prior=s;
cout<<"has insert:"<<e<<endl;
ListTraverse(L);
cout<<"======"<<"after insert:"<<"======"<<endl<<endl;
return (OK);
}
// 刪除帶頭結點的雙鏈循環線性表L的第i個元素,i的合法值為1≤i≤表長
int ListDelete(DuLinkList L)
{
DuLinkList p;
int j=1; // j為計數器
int e;
int i;
cout<<"input the location of the number you want to delete"<<endl;
cin>>i;
while(i<0||i>ListLength(L))
{
//i值不合法
cout<<"illeagle location,please input the correct location:";
cin>>i;
}
p=L->next; // p指向第一個結點
while(p!=L&&j<i) // 順指針向後查找,直到p指向第i個元素或p指向頭結點
{
p=p->next;
j++;
}
if(p==L||j>i) // 第i個元素不存在
{
cout<<"第i個元素不存在"<<endl;
return ERROR;
}
else
{
cout<<"======"<<"before delete:"<<"======"<<endl;
ListTraverse(L);
e=p->data; // 取第i個元素
if(!p) // p=NULL,即第i個元素不存在
return ERROR;
e=p->data;
p->prior->next=p->next;
p->next->prior=p->prior;
free(p);
cout<<"has delete:"<<e<<endl;
ListTraverse(L);
cout<<"======"<<"after delete:"<<"======"<<endl<<endl;
return OK;
}
}
void menu(int c)
{
cout<<"================================================="<<endl;
cout<<"\t\t1----建立"<<endl;
cout<<"\t\t2----插入"<<endl;
cout<<"\t\t3----刪除"<<endl;
cout<<"\t\t4----逆置"<<endl;
//cout<<"\t\t5----菜單"<<endl;
cout<<"\t\t0----退出"<<endl;
cout<<"================================================="<<endl;
cout <<endl<<"input you choice number:";
}
void main()
{
DuLinkList L;
int c=1;
while(c!=0)
{
switch(c)
{
case 0:
break;
case 1:
CreateList_DuL(L);
break;
case 2:
ListInsert_DuL(L);
break;
case 3:
ListDelete(L);
break;
case 4:
ListTraverseBack(L);
break;
default:
cout<<"infeasible choice,input again:"<<endl;
menu(c);
cin>>c;
}
if(c!=0)
{
menu(c);
cin>>c;
}
}
}
❸ 數據結構雙向鏈表如何刪除結點
只學過c語言,嘗試c語言寫一下。讓x節點的前置節點的向後指針域指向x節點的向後指針域指向的節點;讓x節點的後續節點的向前指針域指向x節點的向前指針域指向的節點;釋放x節點;p->llink->rlink= p->rlink;p->rlink->llink= p->llink;free(X);當然,如果雙向鏈表不是循環鏈表,帶頭指針這些,還需要考慮X節點作為第一個節點或者最後一個節點的特殊情況。❹ C語言編寫雙向鏈表刪除
原始核心代碼是有一些問題的。
修改如下:
#include<stdio.h>
#include<stdlib.h>
typedefstructbnode
{
intdata;
structbnode*prior,*next;
}
node,*blink;
voidcreat(blink*L,intn)
{
inti;
blinkp,q=NULL;
for(i=1;i<=n;++i)
{
p=(blink)malloc(sizeof(node));
p->data=i;
p->next=NULL;
p->prior=q;
if(q)
q->next=p;
if(q==NULL)*L=p;
q=p;
}
}
voidprint(blinkL)
{
blinkp=L;
while(p)
{
printf("%5d",p->data);
p=p->next;
}
printf(" ");
}
voidinsert(blink*L,inti,inte)
{
blinkp=*L,s;
intj=1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i)
printf("error");
else
{
s=(blink)malloc(sizeof(node));
s->data=e;
s->prior=p->prior;
if(p->prior)
p->prior->next=s;
else*L=s;
s->next=p;
p->prior=s;
}
}
voidde(blink*L,inti)
{
blinkp=*L,s;
intj=1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i)
printf("error");
else
{
s=p;
if(p->prior)
p->prior->next=p->next;
else
*L=p->next;
p->next->prior=p->prior;
free(s);
}
}
intmain()
{
blinkl;
inti,e;
printf("inputelementnumber:");
scanf("%d",&i);
creat(&l,i);
printf("theorglistis ");
print(l);
printf("inputthenumbertoinsert:");
scanf("%d",&e);
printf("inputtheindextoinsert:");
scanf("%d",&i);
insert(&l,i,e);
printf("afterinsert,thelistis ");
print(l);
printf("inputtheindextodelete:");
scanf("%d",&i);
de(&l,i);
printf("afterdelete,thelistis ");
print(l);
return0;
}
❺ 數據結構(C語言版)中的刪除鏈表中的一個節點
代碼如下:
#include <stdio.h>
#include <stdlib.h>
typedef struct List
{
int a;
List* next;
}list;
void newList(list* l)//創建結點
{
list* a[4];
for (int i = 0; i < 4; i++)
{
a[i] = (list*)malloc(sizeof(list));
a[i]->a = i+1 ;
}
l->next = a[0];
a[0]->next = a[1];
a[1]->next = a[2];
a[2]->next = a[3];
a[3]->next = NULL;
}
void printfList(list* l)//列印結點的數據內容
{
printf("該鏈表的內容是: ");
while (l->next)
{
printf("%d ", l->next->a);
l = l->next;
}
printf(" ");
}
void setList(list* l,int x,int y)
{
list* head = l;
l = l->next;
while (l)
{
if (l->a >=y || l->a <=x)//將結點的數據區與指定區域進行比較
{
head->next = l;//將滿足條件的結點連接在新表的最後一個結點
//指針後移
l = l->next;
head = head->next;
}
else
{
//不滿足的結點進行刪除
list* l1 = l;
l = l->next;
free(l1);
}
}
head->next = NULL;
}
int main()
{
list* l = (list*)malloc(sizeof(List));
newList(l);//初始化鏈表
printfList(l);//輸出舊表內容
setList(l,1,3);//進行修改
printfList(l);//輸出修改後的鏈表
//system("pause");
return 0;
}
(5)用C語言寫雙向鏈表的刪除擴展閱讀
鏈表的特點
1、插入、刪除數據效率高,時間復雜度為O(1)級別(只需更改指針指向即可),隨機訪問效率低,時間復雜度O(n)級別(需要從鏈頭至鏈尾進行遍歷)。
2、和數組相比,內存空間消耗更大,因為每個存儲數據的節點都需要額外的空間存儲後繼指針。
常用的鏈表類型
1、單鏈表
1)每個節點只包含一個指針,即後繼指針。
2)單鏈表有兩個特殊的節點,即首節點和尾節點。用首節點地址表示整條鏈表,尾節點的後繼指針指向空地址null。
3)性能特點:插入和刪除節點的時間復雜度為O(1),查找的時間復雜度為O(n)。
2、循環鏈表
1)除了尾節點的後繼指針指向首節點的地址外均與單鏈表一致。
2)適用於存儲有循環特點的數據,比如約瑟夫問題。
3、雙向鏈表
1)節點除了存儲數據外,還有兩個指針分別指向前一個節點地址(前驅指針prev)和下一個節點地址(後繼指針next)。
2)首節點的前驅指針prev和尾節點的後繼指針均指向空地址。
❻ 使用C語言實現雙向鏈表的建立、刪除和插入
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
struct list{
int data;
struct list *next;
struct list *pre;
};
typedef struct list node;
typedef node *link;
link front=NULL,rear,ptr,head=NULL;
link push(int item){
link newnode=(link)malloc(sizeof(node));
newnode->data=item;
if(head==NULL)
{
head=newnode;
head->next=NULL;
head->pre=NULL;
rear=head;
}
else
{
rear->next=newnode;
newnode->pre=rear;
newnode->next=NULL;
rear=newnode;
}
return head;
}
void makenull(){
front=NULL;
rear=NULL;
}
empty(){
if(front==NULL)
return 1;
else
return 0;
}
int tops(){
if(empty())
return NULL;
else
return rear->data;
}
void pop(){
if(empty())
printf("stack is empty!\n");
else
rear=rear->pre;
}
void display(link l){
link p;
p=l;
while(p!=NULL){
printf("%d->",p->data);
p=p->next;
}
}
void main(){
int n,i;
printf("input your first data!\n");
scanf("%d",&n);
front=push(n);
/*another data*/
for(i=0;i<3;i++)
{
printf("input:\n");
scanf("%d",&n);
push(n);
}
ptr=front;
display(ptr);
printf("\n Please enter any key to pop");
pop();
ptr=front;
display(ptr);
}
❼ C語言中鏈表怎麼刪除結點
有分才有動力啊哥們。
刪除節點很簡單,以單鏈表為例,牢記三點
避免斷鏈,刪除掉節點後,前一個節點的p->next一定要指向後一個節點(如果是頭節點,記得要將新表頭P指向到原來的第二個節點。如果是尾節點,記得要將新的尾節點p->next置為NULL,)。
避免野指針,刪除掉節點後,p->next=NULL;
避免內存泄漏,刪除的節點,要用free釋放堆內存。
如果是雙向鏈表,不過是多了一個對prev操作,道理是一樣的。
❽ c語言雙向鏈表刪除元素問題
問題在於delete_2函數里的free(p);不是將p置為NULL,所以你刪掉以後還會繼續循環。這時你就使用了已經free了的指針,而導致錯誤。
建議將函數delete_2中所有的free(p),改為p=NULL;
並在函數結束的地方free(p)。
❾ 用C語言創建雙向鏈表順時針數到n刪除一個節點,逆時針數到m刪除一個節點,輸出只有一個節點時節點數值
#include<stdio.h>
#include<stdlib.h>
structcyclechain{
structcyclechain*pre;
structcyclechain*next;
unsignedintmessage;
};
typedefstructcyclechainCC;//定義鏈表節點結構
CC*entry=NULL;//環鏈表入口
voidcreatchain(unsignedintm)//建立自然數環鏈
{
CC*lastnode;
unsignedinti;
if(entry==NULL){
entry=(CC*)malloc(sizeof(CC));
entry->pre=entry;
entry->next=entry;
entry->message=1;
}
lastnode=entry;
for(i=2;i<=m;i++){
lastnode->next=(CC*)malloc(sizeof(CC));
lastnode->next->pre=lastnode;
lastnode->next->message=i;
lastnode=lastnode->next;
}
entry->pre=lastnode;
lastnode->next=entry;
}
voidposdel(unsignedintn,CC*entrynode,CC**presentnode)//正向刪除,最後個參數代表刪除後,節點位置
{
while(--n){
entrynode=entrynode->next;
}
*presentnode=entrynode->pre;
printf("posdelmessage:%d ",entrynode->message);
entrynode->pre->next=entrynode->next;
entrynode->next->pre=entrynode->pre;
free(entrynode);
}
voidnegdel(unsignedintk,CC*entrynode,CC**presentnode)//反向刪除,最後個參數代表刪除後,節點位置
{
while(--k){
entrynode=entrynode->pre;
}
*presentnode=entrynode->next;
printf("negdelmessage:%d ",entrynode->message);
entrynode->pre->next=entrynode->next;
entrynode->next->pre=entrynode->pre;
free(entrynode);
}
unsignedcharcheckchain(CC*entry)//判定是否為鏈表最後一個元素
{
if(entry->pre==entry)return1;
elsereturn0;
}
intmain()
{
CC*presentnode;
creatchain(6);//創建鏈表
presentnode=entry;
//一直刪除元素,直到只剩一個元素
while(1){
if(checkchain(presentnode))//檢測是否為最後個元素
break;
posdel(3,presentnode,&presentnode);
if(checkchain(presentnode))
break;
negdel(4,presentnode,&presentnode);
if(checkchain(presentnode))
break;
}
printf("result:%d ",presentnode->message);
free(presentnode);//釋放最後個節點的堆內存
return0;
}
沒做函數參數安全性處理,樓主自己改改
❿ 雙向鏈表 刪除指定節點
int delete(info * h, int no)
{
info t;
if(h == NULL || *h == NULL) return 0;
t = *h;
do{
if(t->no == no){
if(t == *h){ if( t->next == t) *h = NULL;
else{ *h = t->next; t->prior ->next = t->next;t->next ->prior = t->prior;}
}
else {
t->prior ->next = t->next;t->next ->prior = t->prior;
}
free(t);
return 1;
}
t = t->next;
}while(t != *h);
return 0;
}