双向链表C++

双向链表

双向链表中,每个元素节点即有一个只想后继的指针,又有一个指向前驱的指针。
定义一个双向链表类List,包含三个数据成员head,tail,count,分别指指向最左边和最右边节点的指针以及目前节点的个数。

一.节点结构:

struct Node
{
	int x;
	int y;
	Node* next;
	Node* pre;
	Node(int _x,int _y, Node* n=nullptr,Node* p=nullptr)
	{
		x = _x;
		y = _y;
		next = n;
		pre = p;
	}
	friend ostream& operator<<(ostream& os,Node a)//输出重载
	{
		os <<"( "<< a.x << " " << a.y <<" )"<< endl;
		return os;
	}
};

二.类:

class List
{
private:
	Node* head;
	Node* tail;
	int count;
public:
	List();
	~List();
	void Insert(Node* n,int index);//插入n指向的节点
	void Insert(int x, int y, int index);//重载
	void InsertHead(Node* n);//头插
	void InsertHead(int x, int y);//头插重载
	void Delete(int index);//删除指定位置节点
	void Delete(int x,int y);//删除指定节点
	void DeleteTail();//尾删
	Node* Search_Node(int x, int y);//搜寻指定节点,返回节点
	int Search_In(int x, int y);//搜寻指定节点,返回位置
	Node* Search(int index);//返回指定位置处节点
	void Out();//打印链表

};
构造函数和析构函数:

List::List()
{
	head = nullptr;
	tail = nullptr;
	count = 0;
}
List::~List()
{
	while (head != nullptr)
	{
		Node* q = head->next;
		delete head;
		head = q;
	}
}

三.基本操作:

1.查找:

查找下标为index的节点时,当index<count/2则从左向右查找,否则从右向左查找。
Node* List::Search_Node(int x, int y)
{
	Node* q = head;
	while (q != nullptr && (x != q->x || y != q->y))
	{
		q = q->next;
	}
	return q;//未找到则返回nullptr
}
int List::Search_In(int x, int y)
{
	Node* q = head;
	int i=0;
	while (q != nullptr && (x != q->x || y != q->y))
	{
		q = q->next;
		i++;
	}
	if (q==nullptr)//未找到
	{
		return -1;
	}
	else
		return i;
}
Node* List::Search(int index)
{
	if (index < count / 2)//从左向右
	{
		Node* q = head;
		for (int i = 0; i < index; i++)
		{
			q = q->next;
		}
		return q;
	}
	else//从右向左
	{
		Node* q = tail;
		for (int i = 0; i < count-index-1; i++)
		{
			q = q->pre;
		}
		return q;
	}
}

2.插入

void List::Insert(Node* n,int index)//插在第index位置上(位于原index节点之前)
{
	if (index<0 || index>count)//无效索引
	{
		ostringstream s;
		s << "index= " << index << " size = " << count;
		throw s;
	}
	if (index == 0)//头插
	{
		n->pre = nullptr;
		n->next = head;
		head = n;
		if (!n->next)
		{
			tail = n;
		}
		else
		{
			n->next->pre = n;
		}
	}
	else//寻找新节点前驱  进入以下模块则count!=0
	{
		Node* q = head;
		for (int i = 0; i < index-1; i++)//若为i<index则为寻找后继
		{
			q = q->next;
		}
		//在q之后插入
		n->pre = q;
		n->next = q->next;
		q->next = n;
		if (!n->next)//尾指针更新
		{
			tail = n;
		}
		else
		{
			n->next->pre = n;
		}
	}
	count++;
}
void List::Insert(int x, int y, int index)
{
	Node* n = new Node(x, y);
	Insert(n, index);
}
void List::InsertHead(Node* n)
{
	Insert(n, 0);
}
void List::InsertHead(int x, int y)
{
	Insert(x, y, 0);
}

4.删除:

void List::Delete(int index)
{
	if (index<0 || index>=count)//无效索引(此处为》=)
	{
		ostringstream s;
		s << "index= " << index << " size = " << count;
		throw s;
	}
	Node* d;
	if (index == 0)
	{
		d = head;
		head = head->next;
		if (head == nullptr)
			tail = nullptr;//更新尾指针
		else
		{
			head->pre = nullptr;
		}
	}
	else//寻找前驱  进入以下模块则count!=0
	{
		Node* q = head;
		for (int i = 0; i < index - 1; i++)//若为i<index则为寻找后继
		{
			q = q->next;
		}
		d= q->next;
		q->next = q->next->next;
		if (q->next)
		{
			q->next->pre = q;
		}
		else
		{
			tail = q;
		}
	}
	count--;
}
void List::Delete(int x, int y)
{
	int n = Search_In(x, y);
	Delete(n);
}
void List::DeleteTail()
{
	Delete(count - 1);
}

打印及测试

//测试
void List::Out()
{
	cout << head << endl;
	for (Node* q = head; q != nullptr; q = q->next)
	{
		//cout << *q;
		cout << q->pre << "  " << q << "  " << q->next << endl;
	}
	cout << tail << endl;
}

List L;
	L.Insert(1, 2,0);
	L.Insert(1, 2, 0);
	L.Insert(1, 2, 0);
	L.Insert(1, 2, 0);
	L.Insert(1, 2, 0);
	L.Out();
	cout << endl;
	L.Insert(1, 7, 3);
	L.Out();
	cout << endl;
	L.Insert(11, 11, 5);
	L.Out();
	cout << endl;

扫描二维码关注公众号,回复: 1048849 查看本文章

结果如下:

猜你喜欢

转载自blog.csdn.net/qq_40510553/article/details/80110312
今日推荐