一、单链表的创建
结点的定义
typedef struct LNode{
int data;
struct LNode *next;
}LNode, *LinkList; //声明一个节点可以使用 LNode *node; LinkList L;
初始化一个单链表
//初始化一个单链表(包含头节点)
bool InitList(LinkList &L)
{
L = (LNode *) malloc(sizeof(LNode)); //分配内存
if(L == NULL){
return false; //内存申请失败
}
L->next = nullptr; //头节点后暂时没有节点
return true; //初始化成功
}
判断单链表是否为空
//判断节点是否为空
bool Empty(LinkList L)
{
if(L->next == nullptr)//头节点为空
return true;
else
return false;
}
二、单链表的插入(按位序)
//在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList &L, int i, int e)
{
//判断i的合法性
if(i < 1) return false;
LNode *p = L; //指针p指向当前链表头节点
int j = 0; //表示指针p当前指向节点
//循环找到第i-1个节点
while(p != nullptr && j < i-1){ //如果i超出链表长度,p会指向空指针
p = p->next;
j++;
}
return InsertNextNode(p, e); //返回true
}
三、指定节点的插入(前插、后插)
//在指定节点p后插入一个元素e
bool InsertNextNode(LNode *p,int e)
{
if(p == nullptr) return false;
LNode *s = (LNode *) malloc((sizeof(LNode))); //分配内存
//分配失败
if(s == NULL) return false;
//分配成功
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//指定节点的前插操作
bool insertPreNode(LNode *p, int e)
{
if(p == nullptr) return false;
LNode *s = (LNode *) malloc(sizeof(LNode)); //分配内存
//内存分配失败
if(s == NULL) return false;
s->next = p->next;
p->next = s; //新节点s插入到p后
s->data = p->data; //将s的元素复制到p
p->data = e; //p中元素覆盖为e
return true;
}
四、单链表的删除
//指定节点的删除
bool DeleteNode(LNode *p)
{
if(p==NULL)
return false;
LNode *q = p->next; //令q指向*p的后继结点
p->data = p->next->data; //让p和后继结点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q);
return true;
} //时间复杂度 = O(1)
//删除链表第i个位置的元素
//e保存删除的元素值
bool ListDelete(LinkList &L, int i, int &e)
{
//i有效性判断
if(i < 1) return false;
LNode *p = L;
int j=0;
while(p != nullptr && j < i-1){
p = p->next;
j++;
}
if(p == nullptr) return false;
if(p->next == nullptr) return false; //第i-1已经是链表尾部
LNode *q = p->next; //令q指向被删除的结点
e = q->data; //用e返回被删除元素的值
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放结点的存储空间
return true;
}
五、单链表的查找
//单链表的查找
//获取表L中第i个位置元素的值
LNode *GetElem(LinkList L, int i)
{
//有效性判断
if(i < 0) return NULL;
LNode *p = L;
int j=0;
while(p != nullptr && j < i){
p = p->next;
j++;
}
return p;
}
//按值查找元素
LNode * LocateElem(LinkList L, int e){
LNode *p = L->next; //p指向第一个结点
//从第一个结点开始查找数据域为e的结点
while(p!=nullptr && p->data != e){
p = p->next;
}
return p; //找到后返回该结点指针,否则返回NULL
}
六、单链表的长度
//获取单链表的长度
int Length(LinkList L){
int len=0; //统计表长
LNode *p = L;
while(p->next != nullptr){
p = p->next;
len++;
}
return len;
}
七、单链表的建立
前插法:
LinkList List_HeadInsert(LinkList &L){ //逆向建立单链表
LNode *s;
int x;
L = (LinkList)malloc(sizeof(LNode)); //建立头结点
L->next = NULL; //初始为空链表,这步不能少!
scanf("%d", &x); //输入要插入的结点的值
while(x!=9999){ //输入9999表结束
s = (LNode *)malloc(sizeof(LNode)); //创建新结点
s->data = x;
s->next = L->next;
L->next = s; //将新结点插入表中,L为头指针
scanf("%d", &x);
}
return L;
}
后插法:
LinkList List_TailInsert(LinkList &L){ //正向建立单链表
int x; //设ElemType为整型int
L = (LinkList)malloc(sizeof(LNode)); //建立头结点(初始化空表)
LNode *s, *r = L; //r为表尾指针
scanf("%d", &x); //输入要插入的结点的值
while(x!=9999){ //输入9999表结束
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s; //r指针指向新的表尾结点
scanf("%d", &x);
}
r->next = NULL; //尾结点指针置空
return L;
}
完整代码:
#include <iostream>
#include <cstdlib>
using namespace std;
typedef struct LNode{
int data;
struct LNode *next;
}LNode, *LinkList; //声明一个节点可以使用 LNode *node; LinkList L;
//初始化一个单链表(包含头节点)
bool InitList(LinkList &L)
{
L = (LNode *) malloc(sizeof(LNode)); //分配内存
if(L == NULL){
return false; //内存申请失败
}
L->next = nullptr; //头节点后暂时没有节点
return true; //初始化成功
}
//判断节点是否为空
bool Empty(LinkList L)
{
if(L->next == nullptr)//头节点为空
return true;
else
return false;
}
//在指定节点p后插入一个元素e
bool InsertNextNode(LNode *p,int e)
{
if(p == nullptr) return false;
LNode *s = (LNode *) malloc((sizeof(LNode))); //分配内存
//分配失败
if(s == NULL) return false;
//分配成功
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//在第i个位置插入元素e(带头结点)
bool ListInsert(LinkList &L, int i, int e)
{
//判断i的合法性
if(i < 1) return false;
LNode *p = L; //指针p指向当前链表头节点
int j = 0; //表示指针p当前指向节点
//循环找到第i-1个节点
while(p != nullptr && j < i-1){ //如果i超出链表长度,p会指向空指针
p = p->next;
j++;
}
return InsertNextNode(p, e); //返回true
}
//指定节点的前插操作
bool insertPreNode(LNode *p, int e)
{
if(p == nullptr) return false;
LNode *s = (LNode *) malloc(sizeof(LNode)); //分配内存
//内存分配失败
if(s == NULL) return false;
s->next = p->next;
p->next = s; //新节点s插入到p后
s->data = p->data; //将s的元素复制到p
p->data = e; //p中元素覆盖为e
return true;
}
//指定节点的删除
bool DeleteNode(LNode *p)
{
if(p==NULL)
return false;
LNode *q = p->next; //令q指向*p的后继结点
p->data = p->next->data; //让p和后继结点交换数据域
p->next = q->next; //将*q结点从链中“断开”
free(q);
return true;
} //时间复杂度 = O(1)
//删除链表第i个位置的元素
//e保存删除的元素值
bool ListDelete(LinkList &L, int i, int &e)
{
//i有效性判断
if(i < 1) return false;
LNode *p = L;
int j=0;
while(p != nullptr && j < i-1){
p = p->next;
j++;
}
if(p == nullptr) return false;
if(p->next == nullptr) return false; //第i-1已经是链表尾部
LNode *q = p->next; //令q指向被删除的结点
e = q->data; //用e返回被删除元素的值
p->next = q->next; //将*q结点从链中“断开”
free(q); //释放结点的存储空间
return true;
}
//单链表的查找
//获取表L中第i个位置元素的值
LNode *GetElem(LinkList L, int i)
{
//有效性判断
if(i < 0) return NULL;
LNode *p = L;
int j=0;
while(p != nullptr && j < i){
p = p->next;
j++;
}
return p;
}
//按值查找元素
LNode * LocateElem(LinkList L, int e){
LNode *p = L->next; //p指向第一个结点
//从第一个结点开始查找数据域为e的结点
while(p!=nullptr && p->data != e){
p = p->next;
}
return p; //找到后返回该结点指针,否则返回NULL
}
//获取单链表的长度
int Length(LinkList L){
int len=0; //统计表长
LNode *p = L;
while(p->next != nullptr){
p = p->next;
len++;
}
return len;
}
LinkList List_HeadInsert(LinkList &L){ //逆向建立单链表
LNode *s;
int x;
L = (LinkList)malloc(sizeof(LNode)); //建立头结点
L->next = NULL; //初始为空链表,这步不能少!
scanf("%d", &x); //输入要插入的结点的值
while(x!=9999){ //输入9999表结束
s = (LNode *)malloc(sizeof(LNode)); //创建新结点
s->data = x;
s->next = L->next;
L->next = s; //将新结点插入表中,L为头指针
scanf("%d", &x);
}
return L;
}
LinkList List_TailInsert(LinkList &L){ //正向建立单链表
int x; //设ElemType为整型int
L = (LinkList)malloc(sizeof(LNode)); //建立头结点(初始化空表)
LNode *s, *r = L; //r为表尾指针
scanf("%d", &x); //输入要插入的结点的值
while(x!=9999){ //输入9999表结束
s = (LNode *)malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s; //r指针指向新的表尾结点
scanf("%d", &x);
}
r->next = NULL; //尾结点指针置空
return L;
}
int main() {
LinkList L; //声明一个链表
InitList(L); //初始化一个链表
auto a = List_TailInsert(L);
auto cur = a->next;
while(cur!= nullptr){
printf("%d ",cur->data);
cur = cur->next;
}
return 0;
}