当前位置 博文首页 > ice_elephant的博客:数据结构算法之双项链表c/c++实现

    ice_elephant的博客:数据结构算法之双项链表c/c++实现

    作者:[db:作者] 时间:2021-09-16 15:51

    双向链表
    单链表中每个结点除了存储自身数据之后,还存储了下一个结点的地址,因此可以轻松访问 下一个结点,以及后面的后继结点,但是如果想访问前面的结点就不行了,再也回不去了。 例如删除结点 p 时,要先找到它的前一个结点 q,然后才能删掉 p 结点,单向链表只能往 后走,不能向前走。如果需要向前走,怎么办呢?
    这时候我们就需要双向链表登场了,双向链表在单项链表的基础上增加了一个指向前一个元素的指针,它形式如下
    typedef int Elemdata;
    typedef struct _DoubleList{
    Elemdata data; //这里的Elemdata 是自定义的int元素类型
    _DoubleList *next;
    _DoubleList *prev;

    }DoubleList,Node;
    在这里插入图片描述
    /*
    双向链表
    1、双向链表初始化
    2、双向链表前插法
    3、双向链表后插法
    4、双向链表任意位置插入
    5、双向链表删除元素
    6、双向链表获取元素
    7、双向链表确定元素是否存在
    8、双向链表的遍历
    9、双向链表的销毁
    所谓双向链表无疑就是再单项链表的基础上多增加了以恶搞prev指针

    */
    上代码

    #include<stdio.h>
    #include<iostream>
    #include<Windows.h>
    #include<iostream>
    
    using namespace std;
    
    typedef int Elemdata;
    
    typedef struct _DoubleList{
    	Elemdata data;
    	_DoubleList *next;
    	_DoubleList *prev;
    
    }DoubleList,Node;
    
    //1、双向链表初始化
    bool initDoubleList(DoubleList *&L){
    	L= new DoubleList;
    	if(!L)	 return false;
    
    	L->next=NULL;
    	L->prev=NULL;
    
    
    	return true;
    }
    
    //2、双向链表的后插法
    bool insert_end(DoubleList *&L,Node *node){
    	if(!L||!node) return false;
    
    	//查找最后一个结点
    	Node *p=L;
    
    	while(p->next){
    		p=p->next;
    	}
    
    	//找到最后一个结点后p
    	node->next = NULL;
    	node->prev = p;
    	p->next= node;
    
    	return true;
    
    }
    
    //3、双向链表的前面插入法则
    bool insert_front(DoubleList *&L,Node *node){
    	
    	if(!L||!node)return false;
    
    	//前插法则要判断前面的那个元素后面有没有元素
    	Node * p = L;
    	
    	if(!L->next){
    		//如果仅有一个头节点,就先当与尾插法
    		node->next= p->next;//也可以写成node-next =NULL;
    		node->prev = p;
    		p->next = node; 	
    
    	}else{//否则
    		
    		node->next = p->next;
    		p->next->prev = node;
    		node->prev=p;
    		p->next=node;
    	}
    
    	return true;
    
    }
    
    //4、双向链表的任意位置插入
    bool insertPos(DoubleList *&L,int i,Elemdata &e){
    	
    	if(!L||i<1) return false;
    
    	//找到要插入的位置,必须是插入,尾部插入我们在这里不算必须要是在两个元素的中间插入
    	
    	Node *p = L;
    
    	int j=0;
    	while(p&&j<i){
    	
    		p=p->next;
    		j++;
    	}
    
    	//插入位置的next结点必须存在元素
    	if(!p||j!=i)return false;
    	
    	Node *s = new Node;
    	s->data = e;
    
    
    	p->prev->next = s;
    	s->prev = p->prev;
    	s->next = p;
    	p->prev =s;
    
    
    	return true;
    
    
    }
    
    //5、双向链表删除指定位置的元素
    bool deleteElem(DoubleList *&L,int i){
    	
    	if(!L)	return false;
    
    	  int j=0;
    	  Node *p,*d;
    	  p = L;
    	  
    	  //找到该位置的元素
    	  while(j<i&&p){
    		
    		  p = p->next;
    		  j++;
    	  }
    
    	  if(!p||j!=i) return false;
    
    	  //判断该位置的下一个结点是否存在
    	  if(p->next){//下一个结点存在元素
    		 d = p;
    		 p->prev->next = p->next;
    		 p->next->prev = p->prev;
    
    
    	  
    	  }else{
    	  //下一结点不存在
    		 d = p;
    		 
    		 p->prev->next = p->next;
    		 
    
    		 delete d;
    
    	  }
    
    	  return true;
    
    
    }
    //获取元素
    
    bool getElemdata(DoubleList *&L,int i,Elemdata &e){
    	//获取位置为i的元素
    	if(!L)return false;
    
    	DoubleList *p = L;
    	
    	int j =0;
    
    	while(j<i&&p){
    		p=p->next;
    		j++;
    	}
    	if(!p||i!=j) return false;
    
    	e = p->data;
    
    	return true;
    
    
    }
    
    //判断元素是否存在
    bool isExitElemdata(DoubleList *&L,Elemdata &e){
    	
    	if(!L) return false;
    
    	Node *p=L->next;
    
    	while(p&&p->data!=e){
    		p = p->next;
    
    
    	}
    
    	if(!p)
    		return false; //如果是到p=NULL结束循环直接返回
    	else
    		return true;
    
    	//否则 得到元素
    
    
    
    }
    //双向链表的遍历
    void printList(DoubleList *&L){
    	
    	if(!L)return ;
    	DoubleList *p = L->next;
    
    	printf("顺序法遍历:");
    	while(p){
    
    		printf("%d\t",p->data);
    		p=p->next;
    	}
    	printf("\n");
    
    
    
    	DoubleList *last =L;
    
    	while(last->next){
    		last = last->next;
    	}
    
    	//找到最后一个节点后
    	
    	printf("逆序遍历:");
    	while(last->prev){
    
    		printf("%d\t",last->data);
    		last=last->prev;
    	}
    
    	printf("\n");
    
    }
    
    void destoyed(DoubleList *&L){ 
    	if(!L) return ;
    
    	Node *p,*d;
    	p=L;
    
    	while(p){
    		d = p;
    		
    		p=p->next;
    		
    		delete d;
    	}
    	
    	L = NULL; 
    }
    
    //测试代码
    int main(void){
    
    	DoubleList *L = NULL;
    	Node *s;
    	if(initDoubleList(L)){
    		printf("链表初始化成功!\n");
    	}else{
    		printf("链表初始化失败!\n");
    	}
    
    	cout<<"请输入5个元素:"<<endl;
    	
    	for(int i=0;i<5;i++){
    
    		s = new Node;
    		cin>>s->data;
    		
    		insert_end(L,s);
    	}
    	
    	printList(L);
    	int x=5;
    
    	if(insertPos(L,1,x)){