数据结构——10 双向链表插入和删除节点

来源:互联网 发布:按摩垫推荐 知乎 编辑:程序博客网 时间:2024/05/21 18:05

双向链表——插入、删除指定位置和相同节点


双向链表——插入、删除指定位置和相同节点


#include<iostream>using namespace std;struct node       //node结构体,里面有两个个node指针,用来指向上/下一个node对象{int x;node *left;   //指向什么类型的对象,就用什么类型的指针node *right;};node* create(int n)         //创建链表,参数n表示结点的个数,返回类型是结点指针node*{if(n<1)                 //参数检测,链表最少有一个节点{cout<<"error input n!"<<endl;exit(0);}node *head=new node;    //建立头结点node *p=head;           //创建用于往后指的node指针for(int i=1;i<=n;i++){node *temp=new node;      //new一个node指针temp->x=i;p->right=temp;            //将p的right指向创建的temp,把新节点连接到链表后面temp->left=p;             //temp的left指向p,新节点left指向上一个节点p=temp;                   //将p指向新结点temp,即p移动到下一个节点}p->right=NULL;                //创建完成后,p->right为空,最后一个节点的right位nullhead->right->left=NULL;       //创建完成后,第一个节点的left为nullreturn head;}void display(node *head)         //输出链表{node *p;p=head->right;               //p重新指向头结点后的那个结点,即for循环创建的第一个结点if(p==NULL)cout<<"NULL List";while(p!=NULL)               //输出{cout<<p->x<<"  ";p=p->right;}cout<<endl;}void insert(node *head, int pos,int data)      //在链表head指定位置pos插入结点,结点的数据x=data{node *p;p=head;                      //p重新指向头结点,这里没有指向for循环创建的第一个结点,是为了能实现在第一个节点前插入while(--pos)                 //找到插入位置的上一个节点p=p->right;node *temp=new node;         //新节点,这里不能用node *temp;    前面讲过,需要存储数据,所以要new一个temp->x=data; temp->left=p;                //建立左连接temp->right=p->right;        //temp连接上p后面的节点p->right=temp;               //p与temp连接}void remove(node *head,int pos)  //在链表head指定位置pos删除结点{node *p;p=head;                      //p重新指向头结点,这里没有指向for循环创建的第一个结点,是为了能实现删除第一个节点while(--pos)                 //找到删除位置的上一个节点,这里还是采用了单链表的思想,但是,既然有左指针,可以有效利用左指针,看下面的removeSame()函数p=p->right;node *temp;                  //新节点,这里能用node *temp; 因为只是利用了地址,不存储数据temp=p->right;               //temp是将要删除的节点    //这里有一个bug,没有处理左连接p->right=temp->right;        //p跨过将要删除的节点连接后面的节点if(temp->right!=NULL)        //这里判断是不是删除链表最后面的那个节点,如果是,那么temp->right==NULL,下面这句不执行,bug除了temp->right->left=p;         //删除结点后面的结点   指向   被删除节点前面的结点, 双向链表的另一个方向}void removeSame(node *head)      //在链表head中删除相同结点{node *p,*t;node *temp;                  //新节点,这里能用node *temp; 因为只是利用了地址,不存储数据p=head->right;               //p重新指向头结点后的第一个结点,从第一个结点开始比较while(p)   {t=p->right;              //内循环从比较的结点的后一个开始比较while(t){if(p->x==t->x)       //相同结点,删除{             temp=p;                           //temp是找到了将要删除的节点p->left->right=temp->right;       //正向连接链表,有效利用left指针,就不用找到删除结点的前一个结点了//if(temp->right!=NULL)           //每次比较从t开始,t是p的后一个节点,所以内循环可以作为终止条件,这里不用判断p->right->left=temp->left;        //反向连接链表break;}t=t->right;}p=p->right;}}int main(){node *list; list=create(10);             //建立链表display(list);               //输出显示建立的链表,这里是讯链表,不用输出insert(list,11,3);           //经过测试,在开始、最后和中间位置都可以实现插入display(list);remove(list,10);             //经过测试,在开始、最后和中间位置都可以实现删除display(list);insert(list,8,3);  display(list);removeSame(list);display(list);return 0;}

0 0
原创粉丝点击