当先锋百科网

首页 1 2 3 4 5 6 7

链表

  • 链表是一种数据结构,是由一系列的结点构成的。
  • 每一个结点中至少包含两个元素。一个是结点的元素值,另一个指向下一个结点的指针。如果只包含向后的指针,那么就是为单链表。

一个形象的比喻:
单链表其实就是像寻找宝藏一样。例如宝藏需要集齐十块拼图。那么肯定要从第一块拼图开始找起,当你获取了第一块之后,那么第一块拼图会告诉你第二块拼图在哪里,以此类推,当你找寻完十块拼图,也就是遍历了整个单链表。

基本节点,单链表的节点中至少有两个内容:
节点的值
指向下个节点的指针

class Node
{

public:
	int value;
	Node* next;
	Node():value(0),next(NULL)
	{
		
	}
};

.h文件中,单链表实现以下操作

class List
{
private:
	Node* head;//单链表的表头节点
public:
	List();//初始化,并且创建链表头
	~List();
	void createList(int n);//创建链表,n为节点个数
	void travelList();//遍历整个链表
	int getLength();//获取链表的长度
	void insertTail(int data);//尾插法
	void insertHead(int data);//头插
	void insertRand(int pos, int data);//指定位置插入
	void deleteByPos(int pos);//指定位置删除
	void reverseList();
};

1.构造函数,构造链表的表头节点,指针指向NULL,并赋值。

List::List()
{
	head = new Node();
	head->value = 0;
	head->next = NULL;
}

2.创建一个n节点的链表

void List::createList(int n)
{
	
	Node* pNew,* pHead;
	pHead = head;
	for (int i = 0;i < n;i++)
	{
		pNew = new Node();
		pNew->value = i;
		pNew->next = NULL;//新节点的下一个节点为空
		pHead->next = pNew;//倒数第二个节点的下一个节点为新节点
		pHead = pNew;
		//cout << "节点:" << i << "值为 = " << i << endl;
	}
}

3.头插
两个步骤无法交换的原因:
如果先将head->next指向pNew,那么真正的head->next将会失去联系。只有head节点我们一开始就是知道的。所以需要先将head->next赋值给pNew。所有的单链表都是先将后面的地址保存住。
在这里插入图片描述

void List::insertHead(int data)
{
	Node* pHead = head;
	Node* pNew = new Node();//新创建一个节点
	pNew->value = data;
	if (head == NULL)
	{
		head = pNew;
	}
	pNew->next = pHead->next;//先将head后面的节点地址保存住
	pHead->next = pNew;//将head的下一个节点设置为next

}

4.尾插
尾插比较简单,只需要遍历完整个链表,再将新的链表放置于最后一个节点后面即可。

void List::insertTail(int data)
{
	Node* pNew = new Node();
	pNew->value = data;
	pNew->next = NULL;
	Node* pNode = head;
	while (pNode->next != NULL)
	{
		pNode = pNode->next;
	}
	pNode->next = pNew;
}

5.随机位置插入

void List::insertRand(int pos, int data)
{
	if (pos > getLength())
	{
		cerr << "位置错误!";
	}
	Node* pNew = new Node();
	Node* pNode = head;
	pNew->value = data;
	while (pos > 0)
	{
		pNode = pNode->next;
		pos--;
	}
	pNew->next = pNode->next;//先将后面的地址保存住
	pNode->next = pNew;//再链接前面的节点


}

6.遍历

void List::travelList()
{
	if (head == NULL || head->next == NULL)
	{
		cout << "空链表!" << endl;
	}
	Node* pHead = head;
	while (pHead->next != NULL)
	{
		pHead = pHead->next;
		cout << pHead->value << endl;
	}
}

7.获取链表长度,其实和遍历一样

int List::getLength()
{
	Node* pNode = head;
	if (pNode == NULL)
	{
		return 0;
	}
	int count = 0;
	while (pNode->next != NULL)
	{
		pNode = pNode->next;
		count++;
	}
	return count;
}

8.根据位置删除某个节点

void List::deleteByPos(int pos)
{
	Node* p, *q;
	p = head;
	q = p->next;
	while (pos > 0)
	{
		p = p->next;
		q = p->next;
		pos--;
	}
	p->next = q->next;


}

9.反转链表
在这里插入图片描述

void List::reverseList()
{
	if (head == NULL)
	{
		return;
	}
	Node* temp;
	Node* pre = head->next;
	Node* cur = pre->next;
	while (cur != NULL)
	{
		temp = cur->next;
		cur->next = pre;
		pre = cur;
		cur = temp;
	}
	head->next = NULL;
	
}

以下是整个测试代码,如有错误,欢迎指正!

#include <iostream>

using namespace std;

class Node
{

public:
	int value;
	Node* next;
	Node():value(0),next(NULL)
	{
		
	}
};

class List
{
private:
	Node* head;
public:
	List();//初始化,并且创建链表头
	~List();
	void createList(int n);//创建链表,n为节点个数
	void travelList();//遍历整个链表
	int getLength();//获取链表的长度
	void insertTail(int data);//尾插法
	void insertHead(int data);//头插
	void insertRand(int pos, int data);//指定位置插入
	void deleteByPos(int pos);//指定位置删除
	void reverseList();
};

List::List()
{
	head = new Node();
	head->value = 0;
	head->next = NULL;
}

void List::createList(int n)
{
	
	Node* pNew,* pHead;
	pHead = head;
	for (int i = 0;i < n;i++)
	{
		pNew = new Node();
		pNew->value = i;
		pNew->next = NULL;//新节点的下一个节点为空
		pHead->next = pNew;//倒数第二个节点的下一个节点为新节点
		pHead = pNew;
		//cout << "节点:" << i << "值为 = " << i << endl;
	}
}

void List::travelList()
{
	if (head == NULL || head->next == NULL)
	{
		cout << "空链表!" << endl;
	}
	Node* pHead = head;
	while (pHead->next != NULL)
	{
		pHead = pHead->next;
		cout << pHead->value << endl;
	}
}

int List::getLength()
{
	Node* pNode = head;
	if (pNode == NULL)
	{
		return 0;
	}
	int count = 0;
	while (pNode->next != NULL)
	{
		pNode = pNode->next;
		count++;
	}
	return count;
}

void List::insertTail(int data)
{
	Node* pNew = new Node();
	pNew->value = data;
	pNew->next = NULL;
	Node* pNode = head;
	while (pNode->next != NULL)
	{
		pNode = pNode->next;
	}
	pNode->next = pNew;
}

void List::insertHead(int data)
{
	Node* pHead = head;
	Node* pNew = new Node();
	pNew->value = data;
	if (head == NULL)
	{
		head = pNew;
	}
	
	pNew->next = pHead->next;
	pHead->next = pNew;

}

void List::insertRand(int pos, int data)
{
	if (pos > getLength())
	{
		cerr << "位置错误!";
	}
	Node* pNew = new Node();
	Node* pNode = head;
	pNew->value = data;
	while (pos > 0)
	{
		pNode = pNode->next;
		pos--;
	}
	pNew->next = pNode->next;
	pNode->next = pNew;


}

void List::deleteByPos(int pos)
{
	Node* p, *q;
	p = head;
	q = p->next;
	while (pos > 0)
	{
		p = p->next;
		q = p->next;
		pos--;
	}
	p->next = q->next;


}

void List::reverseList()
{
	if (head == NULL)
	{
		return;
	}
	Node* temp;
	Node* pre = head->next;
	Node* cur = pre->next;
	while (cur != NULL)
	{
		temp = cur->next;
		cur->next = pre;
		pre = cur;
		cur = temp;
	}
	head->next = NULL;
	
}

int main()
{
	List * list = new List();
	list->createList(2);
	list->insertHead(666);
	list->insertTail(777);
	list->insertRand(2, 700);
	list->deleteByPos(2);
	//list->reverseList();
	list->travelList();
	
	int length = list->getLength();
	
	cout << "链表长度为 = " << length << endl;
	return 0;
}