データ構造アルゴリズムのダブルネックレステーブルのC / c ++実装


各ノードの二重リンク単一リンクリストは、削除後に独自のデータを保存し、次のノードのアドレスも保存します。したがって、次のノードは後続ノードに簡単にアクセスでき、後続ノードの背後にありますが、前のノードにアクセスする場合は、もう戻れません。たとえば、ノードpを削除する場合、前のノードqを最初に見つけてから、pノードを削除できます。単一リンクリストは、順方向ではなく逆方向にのみ移動できます。前進する必要がある場合はどうなりますか?
このとき、二重リンクリストを表示する必要があります。二重リンクリストは、シングル
ネックレスリストに基づいて前の要素へのポインタを追加しますこれは、typedef int Elemdata;
typedef struct _DoubleList { Elemdatadata ;の形式です。 //ここでElemdataはカスタムですint要素タイプ_DoubleList * next; _DoubleList * prev;


} DoubleList、Node;
ここに画像の説明を挿入します
/ *
二重リンクリスト
1、二重リンクリストの初期化
2、
挿入方法の前の二重リンクリスト3、挿入後の
二重リンクリスト方法4、任意の位置での二重リンクリストの挿入
5、二重リンクリスト削除要素
6、二重リンクリスト取得要素
7、双方向リンクリストは要素が存在するかどうかを決定します
8。
二重リンクリスト9のトラバース、二重リンクリストの破棄。
いわゆる二重リンクリストは次のとおりです。間違いなく、単一のネックレスリストに基づく前のポインタの追加。

* /
コード上

#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)){
    
    
	cout<<"元素"<<x<<"插入成功!"<<endl;
	}else{
    
    
	cout<<"元素"<<x<<"插入失败!"<<endl;
	}
	printList(L);
	int e=22;
	if(isExitElemdata(L,e)){
    
    
	
		cout<<"元素"<<e<<"存在"<<endl;
	}else{
    
    
		cout<<"元素"<<e<<"不存在"<<endl;
	}

	//获取元素

	if(getElemdata(L,1,e)){
    
    
		cout<<"成功获取元素"<<e<<endl;
	}else{
    
    
		cout<<"失败获取元素"<<e<<endl;
	}
	//销毁链表
	destoyed(L);

	if(initDoubleList(L)){
    
    
		printf("链表初始化成功!\n");
	}else{
    
    
		printf("链表初始化失败!\n");
	}


		for(int i=0;i<5;i++){
    
    

		s = new Node;
		cin>>s->data;
		
		insert_end(L,s);
	}

	system("pause");
	return 0;
	}


データ構造アルゴリズムにおけるダブルチェーンの難しさは、理解するのにより多くの時間がかかると考えられています。

おすすめ

転載: blog.csdn.net/weixin_45825875/article/details/115030709