一、简单链表结构
#include <iostream>
#include <string>
using namespace std;
typedef int Etype; // 自定义链表的数据元素为整数。
//定义数据元素节点结构
typedef struct ChainNode
{
Etype data; // 存放结点的数据元素。
ChainNode* next; // 指向下一个结点的指针。
};
//ChainNode* p; //p是指向数据元素结构的指针
//p->data表示当前数据元素的值
//p->next表示下一个元素的地址
//p的值是某数据节点的起始地址
typedef string HeadEtype; // 自定义表头的数据元素为整数。
//定义表头结构
typedef struct HeadNode
{
HeadEtype Hdata; // 存放结点的数据元素。
ChainNode* first; // 指向下一个结点的指针。
};
//将表头结点和若干个数据节点链在一个组成一个链接表
//我们定义一个表头类型的执行变量,这个变量也是一个链表:
//HeadNode* L, * L1, *stud;
或者
//ChainNode L, L1, stud;
//如果表头节点和数据节点的结构是相同的,那么表头节点的结构也可以用
//数据节点的结构类型来定义:
// ChainNode* L, * L1, *stud;
//将表头节点指向数据节点
typedef HeadNode* ChainList;
//创建一个空链表
void CreatChainList(ChainList &L)//输入一个数据节点
{
L = new HeadNode;
L->first = NULL;//表头节点的链接域设为NULL
L->Hdata = "HeadNode类型的数据值";//表头节点的数据域填入相应数据
}
//简单链表L数据元素进行输出
void OutputChainList(ChainList &L) {
//ChainList比ChainNode多一层,L的值是表头结点的地址(包括表头节点+若干数据节点)
//L->first表示第一个数据节点的地址
ChainNode* current = L->first;
while(current){
cout << current->data << endl;
//current的值是当前值的地址
current = current->next;//表示下一个值的地址
}
}
//计算简单链表L的长度
int LengthChainList(ChainList& L) {
//L->first表示第一个数据节点的地址
ChainNode* current = L->first;
int len = 0;
while (current) {
len++;
//current的值是当前值的地址
current = current->next;//表示下一个值的地址
}//最后一个数据节点的地址指向的是0,跳出循环
return len;
}
//删除简单链表L中的所有数据节点
void DestroyChainList(ChainList& L) {
//L->first表示第一个数据节点的地址
ChainNode* current = L->first;//表示第一个值的地址
while (L->first) {
current = current->next;//表示下一个值的地址
delete L->first;//清空指向地址值
L->first = current;//清空目标指向下一个地址
}
}
//简单链表中查找第K个元素
bool GetElemChainList(ChainList &L,int k,Etype &result) {
if (k < 1) return false;
ChainNode *current = L->first;//表示第一个值的地址
int index = 1;
while (index < k && current) {
current = current->next;//表示下一个值的地址
index++;
}
if (current) {//current的值为第K个元素的地址
result = current->data;
return true;
}
//current的值为第K个元素的地址,如果为空,说明不存在第K个节点
return false;
}
//简单链表中查找数据元素X
ChainNode* SearchChainList(ChainList& L, Etype& x) {
//输入x元素的地址,如果找到了则返回地址
ChainNode* current = L->first;//表示第一个值的地址
while (current&¤t->data!=x) {//如果地址不为空,并且该地址的数据不等于x
current = current->next;//指向下一个数据的地址
}
if (current) return current;
return NULL;
}
//简单链表L的第K个元素之后插入元素x
bool InsertChainList(ChainList& L, int k, Etype& x) {
//如果k<0,则返回错误信息
if (k < 0) return false;
ChainNode* current = L->first;//指向第一个值的地址
int index = 1;//当前指向第index个元素
while (index<k&¤t) {//从第一个元素开始,直到current指向第k个元素
index++;
current = current->next;//该值代表下一个元素的地址
}
//跳出循环时index=k,current的值为第k个元素的地址
if (k > 0 && !current) return false;//虽然指向了第k个元素,但是地址为空,则返回错误信息
//以上找到了第k个元素的地址,并且该地址不为空
ChainNode* q = new ChainNode;//新建一个数据元素结构体指针,q值是链表的起始地址
q->data = x;//链表的第一个值存入x
if (k) {
//插入在current之后,current->next表示第k+1元素的地址
q->next = current->next;//将q的下一个值指向原链表的k+1元素,就是把q插到原表k+1元素前面
current->next = q;//再将current->next指向q元素的地址,就是把q插到原表k元素后面。
}
else {//如果k=0,作为第一个元素插入
q->next = L->first;//插到第一个元素前面
L->first = q; //插到表头后面;
}
return true;
}
/*
//如果插入点的指针是Insert,找到插入点的直接前驱节点的算法:
ChainNode* current = L->first;//指向第一个值的地址
while(current->next!=Insert&¤t)//
{
current=current->next;
}
*/
//删除链表中第K个数据元素
bool DeleteChainList(ChainList& L, int k) {
if (k < 1 || L->first) return false;//如果删除元素序号小于0,或者链表第一个元素地址为空
ChainNode* current = L->first;
if (k == 1) {//删除链表第一个元素
L->first = current->next;//直接跨过第一个元素指向第二个元素即可
}
else {//如果不是删除第一个元素,还需要遍历到第K-1个元素的地址
ChainNode* q = L->first;//q指向链表第一个元素,指向的意思就是代表该元素的地址
for (int index = 1; index < k - 1 && q; index++) {//q指向K-1个元素的地址
q = q->next;
}
if (!q || !q->next) return false; //K-1和K元素的地址为空
current = q->next;//current指向第K元素地址
q->next = current->next;//q->next表示第k元素地址,指向第k+1元素
}
delete current;//释放第K元素的内存空间
return true;
}
//如果已知条件是删除点的结点指针,这时候要从链表表头开始查找current的直接前驱节点
/*
ChainNode* q = L->first;
while(q->next != current) {
q = q->next;
}
*/
(二)删除第k个元素