数据结构3-双向链表

本文提供了一个C++实现的单链表类,包括无参构造、有参构造、析构、获取长度、按位查找、按值查找、插入元素、删除元素、判断是否为空、遍历和菜单驱动的功能。示例代码展示了如何处理People类型的链表节点。

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

#include <iostream>
using namespace std;

/*实现单链表无参构造,有参构造,析构,
求长度,按位查找,按值查找,插入元素,
删除元素,判断是否为空,遍历单链表,菜单函数*/

struct People
{
	int id;
	string name;
	int age;
};
template <class Element>
struct Node
{
	Element data;
	Node<Element>* next;
	Node<Element>* prior;
};
template <class Element>
class LinkList
{
	/*实现单链表无参构造,有参构造,析构,
求长度,按位查找,按值查找,插入元素,
删除元素,判断是否为空,遍历单链表,菜单函数*/
public:
	LinkList();
	LinkList(Element a[], int n);
	~LinkList();
	int getLength();
	Element getElement(int i);
	int getLocate(Element x);
	void insert(Element x, int i);
	Element del(int i);
	bool ifEmpty();
	void printList();
	void menu(LinkList<Element> &l);
private:
	Node<Element>* head;

};
/*实现单链表无参构造,有参构造,析构,
求长度,按位查找,按值查找,插入元素,
删除元素,判断是否为空,遍历单链表,菜单函数*/
template <class Element>
LinkList<Element>::LinkList()
{
	head = new Node<Element>;
	head->next = nullptr;
}
template <class Element>
LinkList<Element>::LinkList(Element a[], int n)
{
	head = new Node<Element>;
	
	//头插法
	//for(int i=0;i<n;i++)
	//{
	//	Node<Element>* s = new Node<Element>;
	//	s->data = a[i];
	//	s->next = head->next;
	//	head->next = s;
	//	
	//}
	//尾插法
	Node<Element>* rear = head;

	for (int i = 0; i < n; i++)
	{
		Node<Element>* s = new Node<Element>;
		s->data = a[i];
		s->next = nullptr;
		s->prior = rear;
		rear->next = s;
		rear = s;
	}

}
template <class Element>
LinkList<Element>::~LinkList()
{
	Node<Element>* p = head;
	Node<Element>* q;
	while (p)
	{
		q = p;
		p = p->next;
		delete q;
	}
}
template <class Element>
int LinkList<Element>::getLength()
{
	Node<Element>* p = head->next;
	int count = 0;
	while (p)
	{
		count++;
		p = p->next;
	}
	return count;
}
template <class Element>
Element LinkList<Element>::getElement(int i)
{
	Node<Element>* p = head->next;
	int j = 1;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}//使p指针指向目标元素前一个
	if (p == nullptr)
	{
		throw "查找位置错误";
	}
	else 
		
	//Node<Element>* q = p->next;
		return p->next->data;
}
template <class Element>
int LinkList<Element>::getLocate(Element x)
{
	Node<Element>* p = head->next;
	int j = 1;
	while (p&&p->data.id!=x.id&&p->data.name!=x.name&&p->data.age!=x.age)
	{
		p = p->next;
		j++;
	}
	if (p != nullptr) return j;
	else return 0;
	//此处可以用重载确保people全部信息相等才相等
}
template <class Element>
void LinkList<Element>::insert(Element x, int i)
{
	Node<Element>* p = head->next;
	int j = 1;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}//此段为让p指向第i-1个结点
	if (p == nullptr) throw "插入位置异常";
	Node<Element>* s=new Node<Element>;
	if (p->next != nullptr)
	{
		s->data = x;
		s->next = p->next;
		p->next->prior = s;
		p->next = s;
		s->prior = p;
		p = s;
	}
	else
	{
		s->data = x;
		s->next = nullptr;
		s->prior = p;
		p->next = s;
		p = s;
	}
	//p->next = s;
	//p = s;
	
}
template <class Element>
Element LinkList<Element>::del(int i)
{
	Node<Element>* p = head->next;
	int j = 1;
	while (p && j < i - 1)
	{
		p = p->next;
		j++;
	}//此段为让p指向第i-1个结点
	if (p == nullptr || p->next == nullptr)
		throw "删除位置异常";
	Node<Element>* q;
	Element x;
	//q = p->next;
	//p->next = q->next;
	//x = q->data;
	//delete q;
	q=p->next;
	x = q->data;
	if (q->next)
	{
		q->next->prior = p;
		p->next = q->next;
	}//此时删除的不是最后一个元素
	else
	{
		p->next = nullptr;
	}//此时删除最后一个元素
	delete q;
	return x;
}
template <class Element>
bool LinkList<Element>::ifEmpty()
{
	if (head->next == nullptr) return true;
	else return false;
}
template <class Element>
void LinkList<Element>::printList()
{
	Node<Element>* p = head->next;
	while (p)
	{
		cout << p->data.id << " " << p->data.name << " " << p->data.age << endl;
		p = p->next;
	}
}
template <class Element>
void LinkList<Element>::menu(LinkList<Element> &l)
{
	int choice=0;
	int pId = 0;
	int pAge = 0;
	int pos = 0;
	string pName;
	People p1 = { pId, pName, pAge };
	
	/*实现单链表无参构造,有参构造,析构,
求长度,按位查找,按值查找,插入元素,
删除元素,判断是否为空,遍历单链表,菜单函数*/
	cout <<"-----菜单-----"<< endl;
	cout <<"1.打印链表\t2.判断是否为空"<< endl;
	cout <<"3.插入元素\t4.删除元素"<< endl;
	cout <<"5.按值查找\t6.按位查找"<< endl;
	cout << "7.求表长\t8.其余功能敬请期待"<< endl;
	cout <<"请输入你要实现的操作:";
	cin >> choice;
	cout << endl;
	switch (choice)
	{
	case 1:
		l.printList();
		break;
	case 2:
		if (l.ifEmpty())
		{
			cout << "此表为空表" << endl;
			break;
		}
		else
		{
			cout << "此表非空" << endl;
			break;
		}
		break;
	case 3:
		pId=0; 
		pAge=0;
		pos=0;
		
		cout << "请输入你要插入的人物的id:";
		cin >> pId;
		cout << endl;
		cout << "请输入你要插入的人物的name:";
		cin >> pName;
		cout << endl;
		cout << "请输入你要插入的人物的age:";
		cin >> pAge;
		cout << endl;
		p1={ pId, pName, pAge };
		cout << "请输入你要插入的位置:";
		cin >> pos;
		cout << endl;
		l.insert(p1, pos);
		break;
	case 4:
		pos=0;
		cout << "请输入你要删除的元素序号:";
		cin >> pos;
		cout << endl;
		l.del(pos);
		break;
	case 5:
		pId=0, pAge=0;
		
		cout << "请输入你要查找的人物id:";
		cin >> pId;
		cout << endl;
		cout << "请输入你要查找的人物name:";
		cin >> pName;
		cout << endl;
		cout << "请输入你要查找的人物age:";
		cin >> pAge;
		cout << endl;
		p1={ pId, pName, pAge };
		cout << "该人物在第 " << l.getLocate(p1) << " 位" << endl;
		break;
	case 6:
		pos=0;
		cout << "请输入你要查找的人物位置:";
		cin >> pos;
		cout << endl;
		cout<<"第 "<<pos<<" 位上的人物为:"<<l.getElement(pos).id<<" "<< l.getElement(pos).name<<" "<< l.getElement(pos).age;
		cout << endl;
		break;
	case 7:
		cout << "表长为:" << l.getLength() << endl;
		break;
	default:
		cout << "你输入的数字有误,请重新输入" << endl;
		break;
	}

}
int main()
{

	People p[3] = { {1,"Sam",18},{2,"Kevin",19},{3,"Ben",17} };
	LinkList<People> l(p, 3);
	while (1)
	{
		l.menu(l);
	}


	


	return 0;
}

该文章代码与数据结构2-单链表的区分只有插入元素和删除元素的函数,所以类命名没有更换,可根据需要自行更换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值