前言
线性表的链式存储又称单链表。它是指通过一任意的存储单元来存储线性表中的数据元素。
为了建立数据元素之间的线性关系,对每个链表结点,除存放元素自身的信息外,还需存放一个指向其后继结点的指针。
相关知识:
C++结构体
C++指针
C++引用
类型描述
假定线性表的元素类型为ElemType。
单链表中的结点类型描述如下:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkedList;
此处定义相当于
struct LNode{
ElemType data;
struct LNode *next;
};
typedef struct LNode LNode;
typedef struct LNode *LinkedList;
后文具体实现时用 LNode *p来建立一个单独结点,而用LinkedList 来建立单链表的表头结点。
有关于typedef的使用方法可参考这篇文章。
基本操作的实现
1.基本操作的实现取决于采用哪种存储结构,存储结构不同,算法的实现也不同。
2.“&”表示C++中的引用。
//
// Created by Evian on 2020/2/29.
// 单链表基本操作的实现
//
#include <iostream>
using namespace std;
#define ElemType int //方便更改链表中数据的类型
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkedList;
LinkedList List_HeadInsert(LinkedList &L);
LinkedList List_TailInsert(LinkedList &L);
LNode *GetElem(LinkedList L, int i);
LNode *LocateElem(LinkedList L, ElemType e);
LinkedList Insert_Node(LinkedList &L, int i, ElemType x);
LinkedList Delete_Node(LinkedList L, int i);
void DisplayList(LinkedList L);
int main(){
LinkedList list;
LNode *p;
list = List_TailInsert(list);
DisplayList(list);
list = List_HeadInsert(list);
DisplayList(list);
list = Insert_Node(list, 1, 8);
DisplayList(list);
p = GetElem(list, 1);
cout<<p->data<<endl;
list = Delete_Node(list, 1);
p = LocateElem(list, 8);
cout<<p->data<<endl;
return 0;
}
//采用头插法建立带头结点的单链表
LinkedList List_HeadInsert(LinkedList &L){
LNode *s;
ElemType x;
L = new LNode(); //创建头结点
L->next = nullptr; //初始为空链表
cin>>x;
while(x != 9999){
s = new LNode(); //创建新结点
s->data = x;
s->next = L->next; //插入
L->next = s;
cin>>x;
}
return L;
}
//采用尾插法建立带头结点的单链表
LinkedList List_TailInsert(LinkedList &L){
LNode *s,*r;
ElemType x;
L = new LNode();
L->next = nullptr;
r = L;
cin>>x;
while(x != 9999){
s = new LNode();
s->data = x;
r->next = s;
r = s;
cin>>x;
}
r->next = nullptr; //尾结点置空
return L;
}
//按序号查找节点
LNode *GetElem(LinkedList L, int i){
int j = 1;
LNode *p = L->next;
if (i == 0){
return L; //i=0时返回头结点
}
if (i < 1){
return nullptr;
}
while (p && j<i){
p = p->next;
j++;
}
return p; //返回第i个结点的指针,若i大于表长则返回NULL;
}
//按值查找表结点
LNode *LocateElem(LinkedList L, ElemType e){
LNode *p = L->next;
while(p && p->data != e){
p = p->next;
}
return p;
}
//插入结点
LinkedList Insert_Node(LinkedList &L, int i, ElemType x){
if (i == 0){ //不能在头结点插入;
return L;
}
LNode *p, *s = new LNode();
s->data = x; //s为待插入结点
p = GetElem(L,i-1); //获得插入位置的前驱结点
if (p != nullptr){ //当i不合法时P为NULL
s->next = p->next;
p->next = s;
}
return L;
}
//删除结点
LinkedList Delete_Node(LinkedList L, int i){
LNode *p,*q;
p = GetElem(L, i-1); //获得删除位置的前驱结点
q = p->next;
p->next = q->next;
free(q); //释放结点的存储空间
return L;
}
//遍历打印链表
void DisplayList(LinkedList L){
LNode *p = L->next;
while(p->next != nullptr){
cout<<p->data<<"--->";
p = p->next;
}
cout<<p->data<<endl;
}
如有错误,还请指正!TkY 0.0