目录
1.节点定义
typedef struct LNode {
int data; //数据域
struct LNode* next; //指针域
}LNode,*LinkList;
//对第二个别名的分析:LinkList等价于struct LNode*
//使用LinkList创建的量为指向结构体的指针
//而使用LNode创建的量为结构体本身
2.初始化链表
申请一个空的头结点
void InitList(LinkList& L) {
L = (LinkList)malloc(sizeof(LinkList));
//可以让头结点的data存储链表长度
L->data = 0;
L->next = NULL;
}
3.建立单链表
头插法
//头插法建立单链表
//头插法建立的单链表中节点次序是与输入顺序相反的
LinkList HeadInsert(LinkList& L) {
InitList(L); //初始化链表
int x;
cin >> x;
while (x != 9999) { //输入9999表示结束
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
//s插在头结点和上一个结点之间,让s指向上一个节点
L->next = s;
L->data++; //更新链表长度
cin >> x;
}
return L; //返回头结点指针
}
同样可以再传入一个参数表示要输入的节点数
例:
LinkList HeadInsert(LinkList& L,int n) {
InitList(L);
int x;
while (n--) {
cin>>x;
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
//s插在头结点和上一个结点之间,让s指向上一个节点
L->next = s;
L->data++;
}
return L;
}
尾插法
//尾插法建立单链表
LinkList TailInsert(LinkList& L) {
InitList(L);
LinkList s;
LinkList r = L;//创建一个尾指针,始终指向最后一个结点
int x;
cin >> x;
while (x != 9999) {
s = (LinkList)malloc(sizeof(LNode));
s->data = x;
r->next = s; //相当于前一个结点的指针域指向新的结点s
r = s; //更新r,永远指向最后一个节点
L->data++;
cin >> x;
}
r->next = NULL; //重点 最后一个结点指向空节点
return L; //返回头结点
}
4.遍历操作
//遍历操作
void PrintList(LinkList L) {
//p指向第一个结点
LNode* p = L->next;
//LNode*等同于LinkList,写LinkList p也可以
//p不为空就输出当前结点的值,并令p指向下一个结点
while (p) {
cout << p->data << " ";
p = p->next;
}
//头结点的数据域保存链表长度
cout << "共" << L->data << "个结点";
cout << endl;
}
5.函数求链表长度
//求链表长度
int Length(LinkList L) {
int len = 0;
LinkList p = L->next;
while (p) {
len++;
p = p->next;
}
return len;
}
6.查找操作
//按data查找,返回数据域为data的节点指针
LinkList SearchData(LinkList L,int x) {
LinkList p = L->next;
while (p) {
if (p->data == x)
return p;
p = p->next;
}
cout << "查找失败" << endl;
return NULL;
}
//按位查找,返回第i个节点的指针
LinkList SearchLocade(LinkList L, int i) {
if (i == 0)
return L;
LinkList p = L->next;
int n = 1;
while (p && n < i) {
p = p->next;
n++;
}
return p;
}
//按data查找,返回x是第几个结点,找不到返回-1
int SearchDatai(LinkList L, int x) {
LinkList p = L->next;
int i = 1;
while (p && p->data != x) {
if (p->data == x)
return i;
i++;
p = p->next;
}
return -1;
}
7.插入操作
//插入操作
void Insert(LinkList L, int i, int data) {
if (i > Length(L) + 1) {
cout << "位置错误,插入失败" << endl;
return;
}
LinkList p = SearchLocade(L, i - 1); //按位查找,返回指针
LinkList q = (LinkList)malloc(sizeof(LNode));
q->data = data;
q->next = p->next;
p->next = q;
L->data++; //更新链表长度
}
在链表最后插入n个节点(同尾插法)
//在链表后插入n个结点
void InsertN(LinkList L, int n) {
LinkList s = L;
while (s->next != NULL) //让s指向最后一个结点
s = s->next;
while (n--) {
L->data++;
int x;
cin >> x;
LinkList r = (LinkList)malloc(sizeof(LNode));
r->data = x;
s->next = r;
s = r;
}
s->next = NULL;
}
8.删除操作
删除第i个节点
//删除第i个结点
void DeleteLocade(LinkList L, int i) {
L->data--;
LinkList p = SearchLocade(L, i - 1); //前一个结点
LinkList q = p->next; //待删除的第i个结点
p->next = q->next;
free(q); //释放被删结点的内存(不写也行)
}
删除所有数据域为data的节点
//删除所有数据等于data的结点
void DeleteList(LinkList L, int data) {
LinkList p = L;
while (p->next) {
if (p->next->data == data)
p->next = p->next->next; //删除
else
p = p->next;
}
}
9.连接两个链表MN
//链表链接函数,N接在M后面
LinkList AddList(LinkList M, LinkList N) {
LinkList p = M->next;
LinkList q = N->next;
while (p->next != NULL)
p = p->next; //p成为M链表的最后一个结点
p->next = q; //q接在p后面
return M;
}
10.链表排序
//链表排序函数(冒泡)
void SortList(LinkList L) {
LinkList tail, p, q;
tail = NULL;
while (L->next->next != tail) {
p = L;
q = L->next;
while (q->next != tail) {
if (q->data > q->next->data) {
p->next = q->next;
q->next = p->next->next;
p->next->next = q;
q = p->next; //保证p和q相邻
}
q = q->next;
p = p->next;
}
//循环一遍后排好最后一个结点,且q指向最后一个结点,(tail=q)使tail前移一位
tail = q;
}
}
11.链表逆置
LinkList ReverseList(LinkList L) {
LinkList p = L->next, q = p->next;
LinkList s = nullptr;
while (p) {
p->next = s;
s = p;
p = q;
if (q)q = q->next;
}
L->next = s;
return L;
}
全部代码
#include<iostream>
using namespace std;
typedef struct LNode {
int data;
struct LNode* next;
}LNode,*LinkList;
//对第二个别名的分析:LinkList等价于struct LNode*
//使用LinkList创建的量为指向结构体的指针
//而使用LNode创建的量为结构体本身
//初始化操作,申请一个头节点
//传入一个地址
void InitList(LinkList& L) {
L = (LinkList)malloc(sizeof(LinkList));
//可以让头结点的data存储链表长度
L->data = 0;
L->next = NULL;
}
//遍历操作
void PrintList(LinkList L) {
//传入一个结构体指针
//p从头节点指向第一个结点
LNode* p = L->next;
//LNode*等同于LinkList,写LinkList p也可以
//p不为空就输出当前结点的值,并将p指向下一个结点
while (p) {
cout << p->data << " ";
p = p->next;
}
cout << "共" << L->data << "个结点";
cout << endl;
}
//头插法建立单链表
//头插法建立的单链表中节点次序是与输入顺序相反的
//传入的是头指针的地址
LinkList HeadInsert(LinkList& L) {
InitList(L);
int x;
cin >> x;
while (x != 9999) { //输入9999表示结束
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
//s插在头结点和上一个结点之间,让s指向上一个节点
L->next = s;
L->data++;
cin >> x;
}
return L;
}
//尾插法建立单链表
LinkList TailInsert(LinkList& L) {
InitList(L);
LinkList s;
LinkList r = L;//创建一个尾指针,始终指向最后一个结点
int x;
cin >> x;
while (x != 9999) {
s = (LinkList)malloc(sizeof(LNode));
s->data = x;
r->next = s; //相当于前一个结点的指针域指向新的结点
r = s; //更新r,指向最后一个结点
L->data++;
cin >> x;
}
r->next = NULL;
return L;
}
//求链表长度
int Length(LinkList L) {
int len = 0;
LinkList p = L->next;
while (p) {
len++;
p = p->next;
}
return len;
}
//查找
//按data查找,返回指针
LinkList SearchData(LinkList L,int x) {
LinkList p = L->next;
while (p) {
if (p->data == x)
return p;
p = p->next;
}
cout << "查找失败" << endl;
return NULL;
}
//按位查找,返回指针
LinkList SearchLocade(LinkList L, int i) {
if (i == 0)
return L;
LinkList p = L->next;
int n = 1;
while (p && n < i) {
p = p->next;
n++;
}
return p;
}
//按data查找,返回x是第几个结点,找不到返回-1
int SearchDatai(LinkList L, int x) {
LinkList p = L->next;
int i = 1;
while (p && p->data != x) {
if (p->data == x)
return i;
i++;
p = p->next;
}
return -1;
}
//插入操作
void Insert(LinkList L, int i, int data) {
if (i > Length(L) + 1) {
cout << "位置错误,插入失败" << endl;
return;
}
LinkList p = SearchLocade(L, i - 1); //按位查找,返回指针
LinkList q = (LinkList)malloc(sizeof(LNode));
q->data = data;
q->next = p->next;
p->next = q;
L->data++;
}
//在链表后插入n个结点
void InsertN(LinkList L, int n) {
LinkList s = L;
while (s->next != NULL) //让s指向最后一个结点
s = s->next;
while (n--) {
L->data++;
int x;
cin >> x;
LinkList r = (LinkList)malloc(sizeof(LNode));
r->data = x;
s->next = r;
s = r;
}
s->next = NULL;
}
//删除第i个结点
void DeleteLocade(LinkList L, int i) {
L->data--;
LinkList p = SearchLocade(L, i - 1); //前一个结点
LinkList q = p->next; //待删除的第i个结点
p->next = q->next;
free(q); //释放被删结点的内存
}
//删除所有数据等于data的结点
void DeleteList(LinkList L, int data) {
LinkList p = L;
while (p->next) {
if (p->next->data == data)
p->next = p->next->next;
else
p = p->next;
}
}
//链表链接函数,N接在M后面
LinkList AddList(LinkList M, LinkList N) {
LinkList p = M->next;
LinkList q = N->next;
while (p->next != NULL)
p = p->next; //p成为M链表的最后一个结点
p->next = q;
return M;
}
//链表排序函数(冒泡)
void SortList(LinkList L) {
LinkList tail, p, q;
tail = NULL;
while (L->next->next != tail) {
p = L;
q = L->next;
while (q->next != tail) {
if (q->data > q->next->data) {
p->next = q->next;
q->next = p->next->next;
p->next->next = q;
q = p->next; //保证p和q相邻
}
q = q->next;
p = p->next;
}
//循环一遍后排好最后一个结点,且q指向最后一个结点,(tail=q)使tail前移一位
tail = q;
}
}
//链表逆置
LinkList ReverseList(LinkList L) {
LinkList p = L->next, q = p->next;
LinkList s = nullptr;
while (p) {
p->next = s;
s = p;
p = q;
if (q)q = q->next;
}
L->next = s;
return L;
}
int main() {
int n,i,insert;
LinkList L = TailInsert(L); //创建
PrintList(L); //遍历输出
cout << "插入多少个结点:";
cin >> n;
InsertN(L, n);
PrintList(L);
// cout << Length(L) << endl; //计算长度
// LinkList search1 = SearchData(L, 5); //查找5,找到输出5,找不到提示查找失败
// if(search1!=NULL)
// cout << search1->data << endl;
cout << "在第几个结点前插入一个值:";
cin >> i >> insert;
Insert(L, i, insert);
PrintList(L);
// cout << SearchDatai(L, 4) << endl; //找到4是第几个结点的值,找不到输出-1
// DeleteLocade(L, 2); //删除第2个结点
// PrintList(L);
return 0;
}