C++数据结构——链表(各式链表与案例)

Posted eyes++

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++数据结构——链表(各式链表与案例)相关的知识,希望对你有一定的参考价值。

一:单链表

#include<iostream>
using namespace std;

enum error_code{
	success, underflow, range_error
};

struct node{
	int data;
	node* next;
};

class list{
	public:
		list();
		~list();
		int length()const; // 获得链表长度 
		error_code get_element(const int i, int& x)const; // 按序号取元素 
		node* locate(const int x)const; // 按值查找响应结点 
		error_code insert(const int i, const int x); // 插入结点 
		error_code delete_element(const int i); // 删除结点
		error_code display(); // 显示链表所有元素  
		node* get_head(); // 读取链表表头指针的函数
		void create_R(); // 表尾插入法建表
		void create_H(); // 表头插入法建表 
	private:
		int count;
		node* head;
};

list::list(){
	count = 0;
	head = new node;
	head->next = NULL;
}

list::~list(){
	for(int i = 1; i <= count; i++) 
	    delete_element(i);
}

int list::length()const{
	node* p = head->next;
	int n = 0;
	while(p != NULL){
		n++;
		p = p->next;
	}
	return n;
	// 或者直接 return count; 
} 

error_code list::get_element(const int i, int& x)const{
	node* p = new node;
	p = head->next;
	int j = 1;
	while(p != NULL && j != i)
	{
		p = p->next;
		j++;
	}
	if(p == NULL) return range_error;
	x = p->data;
	return success;
}

node* list::locate(const int x)const{
	node* p = new node;
	p = head->next;
	while(p != NULL)
	{
		if(p->data == x) 
		    return p;
		else
		    p = p->next;
	}
	return NULL;
}

error_code list::insert(const int i, const int x){
	if(i < 1 || i > count + 1) return range_error;
	node* p = new node;
	p = head; // 此时不能指向 head->next, 如果在第一个结点插入,那样会直接在while里死循环 
	int j = 0;
	while(j != i - 1 && p != NULL) // 搜索i-1结点 (p != NULL 的必要性??)
	{
		p = p->next;
		j++;
	}
	node* s = new node;
	s->data = x;
	s->next = p->next;
	p->next = s;
	count++;
	return success;
} 

error_code list::delete_element(const int i){
	if(i < 1 || i > count) return range_error; 
	node* p = new node;
	p = head;
	int j = 0;
	while(j != i - 1 && p != NULL){ // 搜索i-1结点 
		p = p->next;
		j++;
	}
	node* u = new node;
	u = p->next; // 指向待删除结点
	p->next = u->next; // 绕过待删除结点
	delete u;
	count--;
	return success; 
}

error_code list::display(){
	if(length() == 0) return underflow;
	node* s = new node;
	s = head->next;
	while(s != NULL)
	{
		cout << s->data << "  ";
		s = s->next;
	}
	cout << endl;
	return success;
}

node* list::get_head(){
	return head;
}

void list::create_R(){
	int x;
	cin >> x;
	node* rear = head; // 设置尾指针
	while(x != -1) // 设置结束符 
	{
		node* s = new node;
		s->data = x;
		rear->next = s;
		rear = s;
		rear->next = NULL;
		count++;
		cin >> x;
	}
} 

void list::create_H(){
	int x;
	cin >> x;
	while(x != -1) // 设置结束符
	{
		node* s = new node;
		s->data = x;
		s->next = head->next;
		head->next = s;
		count++;
		cin >> x;
	}
}

bool ReferenceError(error_code a)
{
	if(a == underflow)
	{
		cout << "underflow!!" << endl;
		return false;
	}
	if(a == range_error)
	{
		cout << "range_error!!" << endl;
		return false;
	}
	return true;
}

int main()
{
	list L;
	int d;
	L.create_H(); // 初始化链表 
	ReferenceError(L.display()); // 展示链表内容 
	cout << L.length() << endl; // 获得链表长度 
	ReferenceError(L.get_element(3, d)); // 按照索引获得值 
	cout << d << endl;
	ReferenceError(L.delete_element(3)); // 删除结点 
	ReferenceError(L.insert(1, 0)); // 插入结点 
	ReferenceError(L.display());
	
	return 0;
}

二:单循环链表

将单链表的表尾结点中的后继指针改为指向表头结点,就构成了单循环链表,而且单循环链表可以不带头结点,改为单循环链表后,搜索函数就需要改变,否则会进入死循环。

带头结点的单循环链表:

#include<iostream>
using namespace std;

enum error_code{
	success, underflow, range_error
};

struct node{
	int data;
	node* next;
};

class list{
	public:
		list();
		~list();
		int length()const;
		error_code get_element(const int i, int& x)const; 
		node* locate(const int x)const; 
		error_code insert(const int i, const int x); 
		error_code delete_element(const int i);
		error_code display(); 
		node* get_head();
		void create_R();
		void create_H();
	private:
		int count;
		node* head;
};

list::list(){
	count = 0;
	head = new node;
	head->next = head;
}

list::~list(){
	for(int i = 1; i <= count; i++) 
	    delete_element(i);
}

int list::length()const{
	return count; 
} 

error_code list::get_element(const int i, int& x)const{
	if(i < 1) return range_error;
	node* p = new node;
	p = head->next;
	int j = 1;
	while(j != i)
	{
		p = p->next;
		j++;
	}
	x = p->data;
	return success;
}

node* list::locate(const int x)const{
	node* p = new node;
	p = head->next;
	while(p != head)
	{
		if(p->data == x) 
		    return p;
		else
		    p = p->next;
	}
	return NULL;
}

error_code list::insert(const int i, const int x){
	if(i < 1 || i > count + 1) return range_error;
	node* p = new node;
	p = head; 
	int j = 0;
	while(j != i - 1)
	{
		p = p->next;
		j++;
	}
	node* s = new node;
	s->data = x;
	s->next = p->next;
	p->next = s;
	count++;
	return success;
} 

error_code list::delete_element(const int i){
	if(i < 1 || i > count) return range_error;
	if(count == 0) return underflow; 
	node* p = new node;
	p = head;
	int j = 0;
	while(j != i - 1){
		p = p->next;
		j++;
	}
	node* u = new node;
	u = p->next;
	p->next = u->next;
	delete u;
	count--;
	return success; 
}

error_code list::display(){
	if(count == 0) return underflow;
	node* s = new node;
	s = head->next;
	while(s != head)
	{
		cout << s->data << "  ";
		s = s->next;
	}
	cout << endl;
	return success;
}

node* list::get_head(){
	return head;
}

void list::create_R(){
	int x;
	cin >> x;
	node* rear = head;
	while(x != -1)
	{
		node* s = new node;
		s->data = x;
		rear->next = s;
		rear = s;
		rear->next = head;
		count++;
		cin >> x;
	}
} 

void list::create_H(){
	int x;
	cin >> x;
	while(x != -1)
	{
		node* s = new node;
		s->data = x;
		s->next = head->next;
		head->next = s;
		count++;
		cin >> x;
	}
}

bool ReferenceError(error_code a)
{
	if(a == underflow)
	{
		cout << "underflow!!" << endl;
		return false;
	}
	if(a == range_error)
	{
		cout << "range_error!!" << endl;
		return false;
	}
	return true;
}

int main()
{
	list L;
	int d;
	L.create_R(); // 初始化 
	ReferenceError(L.display()); // 展示链表 
	cout << L.length() << endl; // 获得链表长度
	ReferenceError(L.get_element(10, d)); // 按照索引取值
	cout << d << endl; 
	ReferenceError(L.insert(1, 0)); // 插入值 
	ReferenceError(L.delete_element(6)); // 删除值
	ReferenceError(L.display()); 
	return 0;
}

三:链表案例

  • 案例一:设计算法判断链表L中的元素是否是递增的,若递增,返回true,否则返回false
  • 案例二:复制链表A中的内容到B表
  • 案例三:已知递增有序列表A、B分别表示一个集合,设计算法实现A∩B,要求求解结果以相同方式存储。
#include<iostream>
using namespace std;

enum error_code{
	success, underflow, range_error
};

struct node{
	int data;
	node* next;
};

class list{
	public:
		list();
		~list();
		int length()const;
		error_code get_element(const int i, int& x)const; 
		node* locate(const int x)const; 
		error_code insert(const int i, const int x); 
		error_code delete_element(const int i);
		error_code display(); 
		node* get_head();
		void create_R();
		void create_H();
	private:
		int count;
		node* head;
};

list::list(){
	count = 0;
	head = new node;
	head->next = NULL;
}

list::~list(){
	for(int i = 1; i <= count; i++) 
	    delete_element(i);
}

int list::length()const{
	return count; 
} 

error_code list::get_element(const int i, int& x)const{
	node* p = new node;
	p = head->next;
	int j = 1;
	while(p != NULL && j != i)
	{
		p = p->next;
		j++;
	}
	if(p == NULL) return range_error;
	x = p->data;
	return success;
}

node以上是关于C++数据结构——链表(各式链表与案例)的主要内容,如果未能解决你的问题,请参考以下文章

(数据结构)顺序表与链表的基本操作代码以及比较

使用向量类实现堆栈的链表与动态数组

[一周一算法] 链表与插入排序

链表与指针

[单向链表与双向链表的实现]

数据结构——栈(线性表与链表)