DS005-C++模板类实现-单向循环链表

当单链表的最后一个结点的next域存储头结点的地址时,就构成了单向循环链表。

实现时需要注意的地方:

1、初始化时,单向循环链表中只有头结点,next域指向自身;

2、判断p是否为尾结点的条件是: p->next是否和头结点head相等



#include "stdafx.h"


#include <iostream>
using namespace std;

template<typename T>class list
{//单向循环链表 
	struct node
	{
		T data;		
		node *next;
	};
	node *head;//头结点
	int length;
public:
	void init()
	{
		head = new node;
		head->next = head;		
		length = 0;
	}
	list()
	{
		init();
	}
	int size()
	{
		return length;
	}
	void print()
	{
		node *p;
		p = head->next;
		while (p != head)
		{
			cout << p->data << " ";
			p = p->next;
		}
		cout << endl;
	}
	node* creatNode(T x)
	{//为x生成结点,返回结点地址
		node *t;
		t = new node;
		t->data = x;
		t->next = 0;
		return t;

	}
	void insert(node *p, T x)
	{//在指针p所指的结点后面插入x
		node *q, *t;

		t = creatNode(x);

		q = p->next;
		p->next = t;
		t->next = q;
		length++;

	}
	void push_front(T x)
	{

		insert(head, x);

	}
	void push_back(T x)
	{
		node *p;
		p = head;
		while (p->next!=head)
		{
			p = p->next;
		}

		insert(p, x);

	}
	node *Address(int i)
	{//得到第i个元素结点的地址
		if (i<0 || i>length)
			return 0;
		if (i == 0)
			return head;
		if (i == 1)
			return head->next;
		

		int j = 0;
		node *p = head;
		while (j < i)
		{
			p = p->next;
			j++;
		}
		return p;

	}

	void insert(int i, T x)
	{//在链表的第i个数据前面插入x
	 //即在第i-1个元素后面插入x
		node *p;
		if (i == 1)
			push_front(x);
		else if (i == length + 1)
			push_back(x);
		else
		{
			p = Address(i - 1);
			insert(p, x);

		}

	}
	void erase(int i)
	{//删除第i个元素结点
		if (i<1 || i>length)
			return;
		node *q, *t;
		t = Address(i-1);
		q = t->next;
		t->next = q->next;
		
		delete q;
		length--;
	}

	node* find(T x)
	{
		node *p = head->next;
		while (p != head)
		{
			if (p->data == x)
				return p;
			p = p->next;
		}
		return 0;
	}

	~list()
	{
		node *p;
		node *q;
		while (head->next!=head)
		{
			p = head->next;
			head->next = p->next;
			delete p;			
		}
		delete head;
		head = 0;
		length = 0;
	}
};

int main()
{
	list<int> L;
	L.push_front(3);
	L.push_front(2);
	L.push_front(1);

	L.print();

	L.push_back(4);
	L.push_back(5);
	L.push_back(6);
	L.print();

	cout << L.size() << endl;

	cout << (L.Address(6)->data) << endl;

	L.insert(1, 44);
	L.print();
	L.insert(3, 55);
	L.print();
	L.insert(8, 66);
	L.print();

	cout << "begin to delete:\n";
	L.erase(1);
	L.print();
	L.erase(L.size());
	L.print();
	L.erase(3);
	L.print();

	cout << L.find(55)->data << endl;


	return 0;
}

缺点:已知某个结点的指针p,想要获得其前驱结点,仍然需要从头遍历。

猜你喜欢

转载自blog.csdn.net/weixin_43917370/article/details/108565933