引入
链表是最基本的数据结构,它由若干个节点组成,每个节点可以在内存上不连续,通过指针建立联系,一个节点由数据和下一个节点地址组成:
head是用来遍历整个链表的指针。头节点和尾节点顾名思义,分别是第一个节点和最后一个节点。
默认条件下,我们设置head = NULL;
即head为空指针(也可以使用nullptr)
链表在空的情况下,其组成部分有且仅有head指针!
由于链表是由节点组成的,所以我们要先定义一个节点struct(当然可以用class)
//节点结构体
struct Node
{
int data; //数据
Node *next;//下一个节点指针
};
如果不用class List来使节点之间存在联系,那么可以利用main函数来建立:
int main()
{
Node *head, *p, *q, *t; //定义头节点,p,q,t节点
head = NULL; //使head指针为空指针
int n, data;
cout << "请输入链表元素数量:";
//输入链表元素数量
cin >> n;
//创建链表
for (int i = 0; i < n; i++)
{
cin >> data; //输入数据
p = new Node; //新建一个p节点
p->data = data;
p->next = NULL; //默认下,尾节点的下一位也是NULL
if (head == NULL) //如果head是空的
head = p; //让head指针指向p节点
else
q->next = p; //不然就继续往下输入
q = p;
}
//遍历链表
t = head; //利用头节点遍历
while (t != NULL)
{
cout << " " << t->data;
t = t->next;
}
delete p;
return 0;
}
其实也就是下面的程序了:
//List using struct.cpp
#include <iostream>
using namespace std;
struct Node
{
int data; //数据
Node *next;//下一个节点指针
};
int main()
{
Node *head, *p, *q, *t; //定义头节点,p,q,t节点
head = NULL; //使head指针为空指针
int n, data;
cout << "请输入链表元素数量:";
//输入链表元素数量
cin >> n;
//创建链表
for (int i = 0; i < n; i++)
{
cin >> data; //输入数据
p = new Node; //新建一个p节点
p->data = data;
p->next = NULL; //默认下,尾节点的下一位也是NULL
if (head == NULL) //如果head是空的
head = p; //让head指针指向p节点
else
q->next = p; //不然就继续往下输入
q = p;
}
//遍历链表
t = head; //利用头节点遍历
while (t != NULL)
{
cout << " " << t->data;
t = t->next;
}
delete p;
return 0;
}
当然,标题上写了“类与数据结构”。所以结构体不符合我们的预期,于是有了类的版本。
用类实现链表的操作
先来看链表和节点的定义:
class Node
{
public:
friend class List; //与List友元
private:
int data;
Node* next;
};
class List
{
public:
//构造函数与析构函数
List();
~List();
//成员函数
void showMenu(); //菜单显示
void printList(); //遍历链表
void clearList(); //清空链表
void createList(int* value, int n); //创建链表
void insertNode(int value, int pos); //插入新节点
void deleteNode(int pos); //删除指定节点
bool judgeList(); //判断链表是否为空
private:
Node* head;
int len;
};
是的,我们把struct改写成class了,并且新增了List类,表示链表。为了建立联系,我们使用了友元:friend class List; //与List友元
这样成功的在类的高度上链表与节点成功建立了联系。
接下来就是对链表的成员函数和构造函数析构函数:
List::List()
{
head = NULL;
len = 0;
}
List::~List()
{
cout << "GoodBye!";
}
void List::showMenu()
{
cout << "输入序号对应链表的操作:" << endl;
cout << "【0】退出链表系统" << endl;
cout << "【1】创建新链表" << endl;
cout << "【2】插入新节点" << endl;
cout << "【3】删除某节点" << endl;
cout << "【4】遍历整链表" << endl;
cout << "【5】清空整链表" << endl;
}
void List::createList(int* value, int n)
{
Node* q = new Node;
this->len = n;
for (int i = 0; i < n; i++)
{
Node* p = new Node;
p->data = *(value + i);
p->next = NULL;
if (head == NULL)
head = p;
else
q->next = p;
q = p;
}
cout << "创建成功!" << endl;
}
void List::printList()
{
Node* t = head;
while (t != NULL)
{
cout << t->data << ' ';
t = t->next;
}
}
void List::insertNode(int value, int pos)
{
Node* t = head;
int n = 1;
if (pos > len)
{
cout << "不存在该位置的节点!" << endl;
return;
}
else if (pos > 0 && pos < len)
{
while (t != NULL)
{
if (n == pos)
{
Node* p = new Node;
p->data = value;
p->next = t->next;
t->next = p;
this->len++;
cout << "添加成功!" << endl;
break;
}
else
t = t->next;
n++;
}
}
else if (pos == len)
{
while (t != NULL)
{
if (n == pos)
{
Node* p = new Node;
p->data = value;
p->next = NULL;
t->next = p;
this->len++;
cout << "添加成功!" << endl;
break;
}
else
t = t->next;
n++;
}
}
}
void List::deleteNode(int pos)
{
Node* t = head;
int n = 1;
if (pos > len || pos <= 0)
{
cout << "不存在该节点!" << endl;
return;
}
else if (pos > 0 && pos <= len)
{
Node* q = new Node;
while (t != NULL)
{
if (n == pos - 1)
{
q = t->next;
t->next = q->next;
this->len--;
break;
}
else
t = t->next;
n++;
}
cout << "删除成功" << endl;
}
}
void List::clearList()
{
Node* t = new Node;
while (head->next != NULL)
{
t = head->next;
if (t->next == NULL)
{
delete t;
delete head;
this->len = 0;
cout << "清空成功!" << endl;
return;
}
head->next = t->next;
delete t;
}
delete head;
}
bool List::judgeList()
{
if (this->len == 0)
return false;
else
return true;
}
最后,我们来看下完整的代码:
//List using class.cpp
#include <iostream>
using namespace std;
class Node
{
public:
friend class List; //与List友元
private:
int data;
Node* next;
};
class List
{
public:
//构造函数与析构函数
List();
~List();
//成员函数
void showMenu(); //菜单显示
void printList(); //遍历链表
void clearList(); //清空链表
void createList(int* value, int n); //创建链表
void insertNode(int value, int pos); //插入新节点
void deleteNode(int pos); //删除指定节点
bool judgeList(); //判断链表是否为空
private:
Node* head;
int len;
};
List::List()
{
head = NULL;
len = 0;
}
List::~List()
{
cout << "GoodBye!";
}
void List::showMenu()
{
cout << "输入序号对应链表的操作:" << endl;
cout << "【0】退出链表系统" << endl;
cout << "【1】创建新链表" << endl;
cout << "【2】插入新节点" << endl;
cout << "【3】删除某节点" << endl;
cout << "【4】遍历整链表" << endl;
cout << "【5】清空整链表" << endl;
}
void List::createList(int* value, int n)
{
Node* q = new Node;
this->len = n;
for (int i = 0; i < n; i++)
{
Node* p = new Node;
p->data = *(value + i);
p->next = NULL;
if (head == NULL)
head = p;
else
q->next = p;
q = p;
}
cout << "创建成功!" << endl;
}
void List::printList()
{
Node* t = head;
while (t != NULL)
{
cout << t->data << ' ';
t = t->next;
}
}
void List::insertNode(int value, int pos)
{
Node* t = head;
int n = 1;
if (pos > len)
{
cout << "不存在该位置的节点!" << endl;
return;
}
else if (pos > 0 && pos < len)
{
while (t != NULL)
{
if (n == pos)
{
Node* p = new Node;
p->data = value;
p->next = t->next;
t->next = p;
this->len++;
cout << "添加成功!" << endl;
break;
}
else
t = t->next;
n++;
}
}
else if (pos == len)
{
while (t != NULL)
{
if (n == pos)
{
Node* p = new Node;
p->data = value;
p->next = NULL;
t->next = p;
this->len++;
cout << "添加成功!" << endl;
break;
}
else
t = t->next;
n++;
}
}
}
void List::deleteNode(int pos)
{
Node* t = head;
int n = 1;
if (pos > len || pos <= 0)
{
cout << "不存在该节点!" << endl;
return;
}
else if (pos > 0 && pos <= len)
{
Node* q = new Node;
while (t != NULL)
{
if (n == pos - 1)
{
q = t->next;
t->next = q->next;
this->len--;
break;
}
else
t = t->next;
n++;
}
cout << "删除成功" << endl;
}
}
void List::clearList()
{
Node* t = new Node;
while (head->next != NULL)
{
t = head->next;
if (t->next == NULL)
{
delete t;
delete head;
this->len = 0;
cout << "清空成功!" << endl;
return;
}
head->next = t->next;
delete t;
}
delete head;
}
bool List::judgeList()
{
if (this->len == 0)
return false;
else
return true;
}
int main()
{
List l;
int choice;
while (true)
{
l.showMenu();
cin >> choice;
if (choice == 0)
{
break;
}
else if (choice == 1)
{
if (l.judgeList())
{
cout << "请清空链表再执行此操作" << endl;
continue;
}
int n;
cout << "输入链表元素个数,然后逐个输入:";
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
cin >> *(arr + i);
}
l.createList(arr, n);
}
else if (choice == 2)
{
if (!(l.judgeList()))
{
cout << "请先创建链表!" << endl;
continue;
}
int value, pos;
cout << "请输入要插入的数值:";
cin >> value;
cout << "位置:";
cin >> pos;
l.insertNode(value, pos);
}
else if (choice == 3)
{
if (!(l.judgeList()))
{
cout << "链表是空的!" << endl;
continue;
}
int pos;
cout << "请输入要删除节点的位置:";
cin >> pos;
l.deleteNode(pos);
}
else if (choice == 4)
{
if (!(l.judgeList()))
{
cout << "链表是空的!" << endl;
continue;
}
cout << "下面将打印链表元素:";
l.printList();
cout << endl
<< "打印结束" << endl;
}
else if (choice == 5)
{
if (!(l.judgeList()))
{
cout << "链表本来就是空的!" << endl;
continue;
}
l.clearList();
}
else
{
cout << "请规范输入!" << endl;
}
cout << endl << "###################################" << endl << endl;
}
return 0;
}