每个单链表都有一个头指针,有时为了方便操作,还会给链表增加一个不存放数据的头节点(也可以存放表长等信息)
单链表的基本操作
//单链表的基本操作
#include <iostream>
#define ElemType int
//链表L,L表示该链表的名称或链表首地址,又称为头指针
typedef struct Lnode {
ElemType data;//每个节点包含两个域,数据域和指针域
struct Lnode* next;
}Lnode,*LinkList;//将结构体等价于类型名Lnode,指针Linklist
//LinkList为struct Lnode*的别名。Lnode为struct Lnode的别名。
//1.初始化
//指构建一个空表,先创建一个头节点,不存储数据,然后令其指针域为空
bool InitList_L(LinkList& L) {
//L表示节点,也即指节点的地址,L->data为节点数据,L->next为下个节点的地址
L = new Lnode;//生成新节点作为头节点,用头指针L指向头节点
if (!L)
return false;
L->next = NULL;//头节点的指针域置空
return true;
}
//创建
//创建单链表分为头插法和尾插法两中,头插法指每次把新节点插入到头节点后面,尾插法是指每次把新节点链接到链接表的尾部
//头插法
void CreateList_H(LinkList &L) {
int n;
LinkList s;
L = new Lnode;
L->next = NULL;
std::cout << "请输入元素个数n" << std::endl;
std::cin >> n;
std::cout << "请依次输入n个元素" << std::endl;
std::cout << "头插法创建链表"<<std::endl;
while (n--) {
s = new Lnode;
std::cin >> s->data;
s->next = L->next;
L->next = s;
}
}
//尾插法
void CreateList_R(LinkList &L) {
int n;
LinkList s, r;
L = new Lnode;
L->next = NULL;//创建一个带头节点的空链表
r = L;//尾指针r指向头节点
std::cout << "请输入元素个数n" << std::endl;
std::cin >> n;
std::cout << "请依次输入n个元素" << std::endl;
std::cout << "尾插法创建单链表" << std::endl;
while (n--) {
s = new Lnode;
std::cin >> s->data;
s->next = NULL;
r->next = s;//将新节点s插入到尾节点r之后,将r
r = s; //指向新的尾节点s
}
}
//取值
//一个链表是由头指针标识的,一旦头指针改动或丢失,这个链表就不完整或者就找不到了。
//所以链表头指针不能轻易改动。如果需要指针移动,可定义一个指针变量进行移动。
bool GetElem_L(LinkList L, int i, int& e) {
//在带头节点的单链表L中查找第i个元素,用e记录L中第i个元素的值
int j;
LinkList p;
p = L->next;//p指向第一个数据节点
j = 1;//j为计时器
while (j < i && p) {//直到p指向第i个元素或p为空
p = p->next;
j++;
}
if (!p || j > i)
return false;
e = p->data;
return true;
}
//查找
//在单链表中查找是否存在元素e
bool LocateElem_L(LinkList L,int e) {
LinkList p;
p = L->next;
while (p && p->data != e)
p = p->next;
if (!p)
return false;
return true;
}
//插入
//在L链表第i个元素前插入数值e
bool ListInsert_L(LinkList L,int i,int e) {
int j = 0;
LinkList s, p;
p = L;
while (p && j < i - 1) {
p = p->next;
j++;
}
if (!p || j > i - 1)
return false;
s = new Lnode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
//删除
bool ListDelete_L(LinkList &L,int i) {
//删除第i个元素
LinkList p, q;
int j = 0;
p = L;
while ((p->next)&&(j<i-1)) {
p = p->next;
j++;
}
if (!(p->next) || (j > i - 1))
return false;
q = p->next;//临时保存被删节点的地址以备释放空间
p->next = q->next;
delete q;
return true;
}