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

本文探讨了单链表和单循环链表的实现,包括判断链表元素递增、复制链表内容以及求两个有序链表的交集算法。通过实例展示了如何在C++中操作和验证链表结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一:单链表

#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* 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; 
	int j = 0;
	while(j != 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){
		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;
}

// 判断是否递增
void isAdd()
{
	cout << "判断递增" << endl;
	// 初始化题目条件 
	list L;
	int d1, d2, i;
	L.create_R();
	ReferenceError(L.display());
    int length = L.length(); // 避免多次计算长度浪费性能 
	
	// 开始操作
	for(i = 1; i < length; i++)
	{
		ReferenceError(L.get_element(i, d1));
	    ReferenceError(L.get_element(i + 1, d2));
	    if(d1 > d2)
	    {
	        cout << "不是递增的!!" << endl;
	        break;	    	
		}
	}
	if(i == length)
	    cout << "是递增的!!" << endl;
}
	
// 复制链表
void copy()
{
	cout << "复制链表" << endl;
	// 初始化题目条件 
	list La, Lb;
	int ia, ib, d;
	La.create_R();
	ReferenceError(La.display());
	
	// 开始操作
	ia = La.length();
	for(ib = 1; ib <= ia; ib++)
	{
		ReferenceError(La.get_element(ib, d));
		ReferenceError(Lb.insert(ib, d));
	}
	ReferenceError(Lb.display());
}
	
// 实现 A ∩B 
void intersection()
{
	cout << "实现交集" << endl;
	//初始化题目条件
	list La, Lb, Lc;
	int ia = 1, ib = 1, ic = 1; 
	int x, y;
	La.create_R();
	Lb.create_R();
	ReferenceError(La.display());
	ReferenceError(Lb.display());

	// 开始操作
	int l1 = La.length();
	int l2 = Lb.length();
	while(ia <= l1 && ib <= l2)
	{
		ReferenceError(La.get_element(ia, x));
		ReferenceError(Lb.get_element(ib, y));
		if(x == y)
		{
			ReferenceError(Lc.insert(ic, x));
			ic++;
			ia++;
			ib++;
		}
		if(x > y)
		{
			ReferenceError(Lc.insert(ic, y));
			ic++;
			ib++;
		}
		if(x < y)
		{
			ReferenceError(Lc.insert(ic, x));
			ic++;
			ia++;
		}		
	}
	while(ia <= l1)
	{
		ReferenceError(La.get_element(ia, x));
		ReferenceError(Lc.insert(ic, x));
		ic++;
		ia++;
	}
	while(ib <= l2)
	{
		ReferenceError(Lb.get_element(ib, y));
		ReferenceError(Lc.insert(ic, y));
		ic++;
		ib++;
	}
	ReferenceError(Lc.display());
}

int main()
{
	// 判断是否递增
	isAdd();
	
	// 复制链表
	copy();
	
	// 实现 A ∩B 
	intersection();
	
	return 0;
}

更多内容大家可以前往我的个人博客浏览:eyes++的个人空间

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值