链表
- 链表是一种数据结构,是由一系列的结点构成的。
- 每一个结点中至少包含两个元素。一个是结点的元素值,另一个指向下一个结点的指针。如果只包含向后的指针,那么就是为单链表。
一个形象的比喻:
单链表其实就是像寻找宝藏一样。例如宝藏需要集齐十块拼图。那么肯定要从第一块拼图开始找起,当你获取了第一块之后,那么第一块拼图会告诉你第二块拼图在哪里,以此类推,当你找寻完十块拼图,也就是遍历了整个单链表。
基本节点,单链表的节点中至少有两个内容:
节点的值
指向下个节点的指针
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;
}