Implementación de clase de plantilla DS005-C ++: lista enlazada circular unidireccional

Cuando el siguiente campo del último nodo de la lista enlazada individualmente almacena la dirección del nodo principal, se forma una lista enlazada individualmente.

Cosas a las que prestar atención al implementar:

1. Durante la inicialización, solo existe el nodo principal en la lista enlazada circular unidireccional, y el siguiente campo apunta a sí mismo;

2. La condición para juzgar si p es el nodo final es: si p-> siguiente es igual a la cabeza del nodo principal



#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;
}

Desventaja: conociendo el puntero p de un determinado nodo, si desea obtener el nodo predecesor, aún debe recorrerlo desde el principio.

Supongo que te gusta

Origin blog.csdn.net/weixin_43917370/article/details/108565933
Recomendado
Clasificación