链表 - 线性表
链表 - 用一组任意的存储单元存储线性表的数据元素(这组存储单元不一定连续)。
单链表 - 链表的每个结点只包含一个指针域。
分类:单链表, 循环链表,双向链表。
单链表
单链表包含的基本运算:单链表的建立,查询,插入,删除。
单链表相关操作 - 代码实现(C语言)
//链表
// Created by yanwosky4 on 2018/6/18.
//
// 数据的类型
#include "stdio.h"
#include "stdlib.h"
// 数据的类型
typedef int ElemType;
// 链表节点的类型
typedef struct LNode {
ElemType data;
LNode* next;
} LNode; // LNode 节点的别名
typedef LNode* LinkList;
LinkList head; // 头节点
// 建立链表 - 头插入法 当输入-1时终止
LinkList create_LinkListByHead () {
LinkList L; // 头节点
LinkList p;
ElemType x;
// 建立带头节点的空链表
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
printf("please enter number\n");
scanf("%d", &x);
while (x != -1) {
p = (LinkList)malloc(sizeof(LNode));
p->data = x;
p->next = L->next;
L->next = p;
printf("please enter number\n");
scanf("%d",&x);
}
return L;
}
// 建立链表 - 尾插入法 当输入-1时终止
LinkList create_LinkListByTail() {
LinkList L;
LinkList p;
LinkList r;
ElemType x;
// 建立空链表
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
r = L;
printf("please enter number\n");
scanf("%d", &x);
while (x != -1) {
p = (LinkList)malloc(sizeof(LNode));
(*p).data = x;
(*p).next = NULL;
(*r).next = p;
r = p;
printf("please enter number\n");
scanf("%d", &x);
}
return L;
}
// 计算单链表的长度
int length_LinkList(LinkList L) {
LinkList p = L;
int count = 0;
while (p->next != NULL) {
count += 1;
p = p->next;
}
return count;
}
// 查找单链表的第i个节点 i从1开始 (可行)
LinkList getPositionNode_LinkList(LinkList L, int i) {
LinkList p = L;
int j = 0;
while (p->next != NULL && j < i) {
j += 1;
p = p->next;
}
if (j == i) {
return p;
} else { // 若查找不到元素, 返回NULL
return NULL;
}
}
// 查找某个值在链表中首次出现所在的节点
LinkList getX_LinkList(LinkList L, ElemType x) {
LinkList p = L->next;
while (p != NULL && p->data != x) { // 继续向后查找的条件
p = p->next;
}
return p;
}
// 单链表的前插入节点
LinkList insert_LinkList(LinkList L, ElemType x, int i) {
LinkList p = L;
int j = 0;
while (p != NULL && j < (i - 1)) {
j += 1;
p = p->next;
}
if (p == NULL || j > i - 1) {
printf("参数i错误");
exit(1);
}
LinkList s = (LinkList)malloc(sizeof(LNode));
s->data = x;
s->next = p->next;
p->next = s;
return L;
}
// 删除单链表的i个节点 i从1开始(***)
LinkList delete_LinkList(LinkList L, int i, ElemType &e) { // e为引用
LinkList p;
int j = 0;
while (p && j < (i - 1)) {
j += 1;
p = p->next;
}
if (p == NULL || j > (i -1)) {
printf("参数i异常");
}
LinkList q = p->next; // q为第i个节点
p->next = q->next;
e = q->data;
free(q); // 释放*q节点的存储空间
return L;
}
// 例题
// 非递减有序链表A⬆,B⬆合并为一个非递增的有序链表C⬇; 不允许重新申请空间
LinkList merge_LinkList(LinkList A, LinkList B) {
LinkList C;
LinkList p, q;
LinkList s; // 带插入的临时节点
p = A->next;
q = B->next;
C = A;
C->next = NULL;
free(B);
while (p && q) {
if (p->data < q->data) {
s = p;
p = p->next;
} else {
s = q;
q = q->next;
}
// 链表的头插入法
s->next = C->next;
C->next = s;
}
if (!p) {
p = q;
}
while (p) {
s = p;
p = p->next;
s->next = C->next;
C->next = s;
}
return C;
}