❶ 关于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;
}