当前位置:首页 » 编程语言 » 用C语言写双向链表的删除
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

用C语言写双向链表的删除

发布时间: 2023-01-20 08:01:01

❶ 关于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语言中链表怎么删除结点

有分才有动力啊哥们。

删除节点很简单,以单链表为例,牢记三点

  1. 避免断链,删除掉节点后,前一个节点的p->next一定要指向后一个节点(如果是头节点,记得要将新表头P指向到原来的第二个节点。如果是尾节点,记得要将新的尾节点p->next置为NULL,)。

  2. 避免野指针,删除掉节点后,p->next=NULL;

  3. 避免内存泄漏,删除的节点,要用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;
}