一、线性表
1. 顺序表的实现——静态分配
#include <stdio.h>
#define MaxSize 10 // 定义最大长度
typedef struct {
int data[MaxSize]; // 用静态数组存放数据元素
int length; // 顺序表的当前长度
} SqList;
// 初始化一个顺序表
void InitList(SqList &L) {
for (int i = 0; i < MaxSize; i++)
L.data[i] = 0; // 将所有数据元素设置为默认初始值
L.length = 0; // 顺序表初始长度为0
}
// 获取第i个位置的元素
int GetElem(SqList L, int i) {
return L.data[i - 1];
}
// 获取某个值的指定位置
int LocateElem(SqList L, int e) {
for (int i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;
return 0;
}
int main()
{
SqList L; // 声明一个顺序表
InitList(L); // 初始化顺序表
return 0;
}
2. 顺序表的实现——动态分配
#include <stdio.h>
#include <stdlib.h>
#define InitSize 10 // 默认的最大长度
typedef struct {
int* data; // 指示动态分配数组的指针
int MaxLSize; // 顺序表的最大容量
int length; // 顺序表的当前长度
} SeqList;
// 初始化一个顺序表
void InitList(SeqList &L) {
// 用malloc函数申请一片连续的存储空间
L.data = (int *) malloc(InitSize * sizeof(int));
L.length = 0;
L.MaxLSize = InitSize;
}
// 增加动态数组的长度
void IncreaseSize(SeqList &L, int len) {
int* p = L.data;
L.data = (int *) malloc((L.MaxLSize + len) * sizeof(int));
for (int i = 0; i < L.length; i++) {
L.data[i] = p[i];
}
L.MaxLSize = L.MaxLSize + len;
free(p);
}
// 获取第i个位置的元素
int GetElem(SeqList L, int i) {
return L.data[i - 1];
}
// 获取某个值的指定位置
int LocateElem(SeqList L, int e) {
for (int i = 0; i < L.length; i++)
if (L.data[i] == e)
return i + 1;
return 0;
}
int main()
{
SeqList L; // 声明一个顺序表
InitList(L); // 初始化顺序表
// 增加动态数组的长度
IncreaseSize(L, 5);
return 0;
}
3. 单链表的实现——无头结点
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data; // 每个节点存放一个数据元素
struct LNode* next; // 指针指向下一个节点
} LNode, *LinkList;
// 初始化一个空的单链表(不带头结点)
bool InitList(LinkList &L) {
L = NULL; // 空表,暂时没有任何节点
return true;
}
// 判断单链表是否为空
bool Empty(LinkList L) {
return L == NULL;
}
// 在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, int e) {
if (i < 1) return false;
if (i == 1) { // 插入第1个节点的操作跟其他节点的操作不同
LNode *s = (LNode *) malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s; // 头节点指向新节点
return true;
}
LNode *p; // 指针p指向当前扫描到的节点
int j = 1; // 当前p指向的是第1个节点
p = L; // p指向第1个节点(注意:不是头结点)
while (p != NULL && j < i - 1) { // 循环找到第i-1个节点
p = p->next;
j++;
}
if (p == NULL) return false; // i的值不合法
LNode *s = (LNode *) malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s;
return true; // 插入成功
}
// 后插操作:在p节点之后插入元素e
bool InsertNextNode(LNode *p, int e) {
if (p == NULL) return false;
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == NULL) return false; // 内存分配失败
s->data = e; // 用节点s保存元素e
s->next = p->next;
p->next = s; // 将节点s连到p之后
return true;
}
// 前插操作:在p节点之前插入节点s
bool InsertPriorNode(LNode *p, LNode *s) {
if (p == NULL || s == NULL) return false;
s->next = p->next;
p->next = s; // s连到p之后
int temp = p->data; // 交换数据域部分
p->data = s->data;
s->data = temp;
return true;
}
// 删除指定节点p
bool ListDelete(LNode *p) {
if (p == NULL) return false;
LNode *q = p->next;
p->data = p->next->data;
p->next = q->next;
free(q);
return true;
}
// 求表的长度
int Length(LinkList L) {
LNode *p = L;
int len = 0;
while (p->next != NULL) {
p = p->next;
len++;
}
return len;
}
4. 单链表的实现——带头结点
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data; // 每个节点存放一个数据元素
struct LNode* next; // 指针指向下一个节点
} LNode, *LinkList;
// 初始化一个空的单链表(带头结点)
bool InitList(LinkList &L) {
L = (LNode *) malloc(sizeof(LNode)); // 分配一个头结点
if (L == NULL) return false;
L -> next = NULL;
return true;
}
// 判断单链表是否为空
bool Empty(LinkList L) {
return L -> next == NULL;
}
// 在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, int e) {
if (i < 1) return false;
LNode *p; // 指针p指向当前扫描到的节点
int j = 0; // 当前p指向的第几个节点
p = L; // L指向头节点,头结点是第0个节点(不存数据)
while (p != NULL && j < i - 1) {
p = p -> next;
j++;
}
if (p == NULL) return false; // i的值不合法
LNode* s = (LNode *) malloc(sizeof(LNode));
s->data = e;
s->next = p->next;
p->next = s; // 将节点s连到p之后
return true; // 插入成功
}
// 后插操作:在p节点之后插入元素e
bool InsertNextNode(LNode *p, int e) {
if (p == NULL) return false;
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == NULL) return false; // 内存分配失败
s->data = e; // 用节点s保存元素e
s->next = p->next;
p->next = s; // 将节点s连到p之后
return true;
}
// 前插操作:在p节点之前插入节点s
bool InsertPriorNode(LNode *p, LNode *s) {
if (p == NULL || s == NULL) return false;
s->next = p->next;
p->next = s; // s连到p之后
int temp = p->data; // 交换数据域部分
p->data = s->data;
s->data = temp;
return true;
}
// 按位序删除:删除第i个位置的元素,并用e返回删除元素的值
bool ListDelete(LinkList &L, int i, int &e) {
if (i < 1) return false;
LNode *p; // 指针p指向当前扫描到的节点
int j = 0; // 当前p指向的是第几个节点
p = L; // L指向头结点,头结点是第0个节点(不存数据)
while (p != NULL && j < i - 1) { // 循环找到第i-1个节点
p = p->next;
j++;
}
if (p == NULL) return false; // i值不合法
if (p->next == NULL) return false; // 第i-1个节点之后已无其他节点
LNode *q = p->next; // 令q指向被删除的节点
e = q->data; // 用e返回该元素的值
p->next = q->next; // 将*q节点从链中断开
free(q); // 释放节点的存储空间
return true; // 删除成功
}
// 按位查找:返回第i个元素
LNode* GetElem(LinkList L, int i) {
if (i < 0) return NULL;
LNode *p; // 指针p指向当前扫描的节点
int j = 0; // 当前p指向的是第几个节点
p = L; // L指向头结点,头结点是第0个节点
while (p != NULL && j < i) { // 循环找到第i个节点
p = p->next;
j++;
}
return p;
}
// 按值查找,找到数据域为e的节点
LNode* LocateElem(LinkList L, int e) {
LNode *p = L->next;
// 从第1个节点开始查找数据域为e的节点
while (p != NULL && p->data != e)
p = p->next;
return p; // 找到后返回该节点的指针,否则返回NULL
}
// 尾插法建立单链表
LinkList List_TailInsert(LinkList &L) {
int x;
L = (LinkList) malloc(sizeof(LNode)); // 建立头结点
LNode *s, *r = L; // r为表尾指针
scanf("%d", &x); // 输入节点的值
while (x != 9999) {
s = (LNode *) malloc(sizeof(LNode));
s->data = x;
r->next = s;
r = s;
scanf("%d", &x);
}
r->next = NULL;
return L;
}
// 头插法建立单链表
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;
}
5. 双链表(带头结点)
#include <stdio.h>
#include <stdlib.h>
typedef struct DNode {
int data;
struct DNode *prior, *next;
} DNode, *DLinkList;
// 初始化双链表
bool InitDLinkList(DLinkList &L) {
L = (DNode *) malloc(sizeof(DNode)); // 分配一个头结点
if (L == NULL) return false; // 内存不足,分配失败
L->prior = NULL;
L->next = NULL;
return true;
}
// 判断双链表是否为空
bool Empty(DLinkList L) {
return L->next == NULL;
}
// 在p节点之后插入s节点
bool InsertNextDNode(DNode *p, DNode *s) {
if (p == NULL || s == NULL) return false; // 非法参数
s->next = p->next;
if (p->next != NULL) // 如果p节点有后继节点
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
// 双链表的删除
bool DeleteNextDNode(DNode *p) {
if (p == NULL) return false;
DNode *q = p->next; // 找到p的后继节点q
if (q == NULL) return false; // p没有后继节点
p->next = q->next;
if (q->next != NULL) // q节点不是最后一个节点
q->next->prior = p;
free(q); // 释放节点空间
return true;
}
// 销毁双链表
void DestroyList(DLinkList &L) {
// 循环释放各个数据节点
while (L->next != NULL)
DeleteNextDNode(L);
free(L); // 释放头结点
L = NULL; // 头指针指向NULL
}
// 后向遍历双链表
void BackPrint(DLinkList L) {
DNode *p = L->next;
while (p != NULL) {
// 对节点p做处理,比如打印
p = p->next;
}
}
// 前向遍历双链表(跳过头结点)
void FrontPrint(DNode *p) {
while (p->prior != NULL) {
// 对节点p做处理,比如打印
p = p->prior;
}
}
6. 循环链表
循环单链表
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode {
int data;
struct LNode *next;
} LNode, *LinkList;
// 初始化循环单链表
bool InitDLinkList(LinkList &L) {
L = (LNode *) malloc(sizeof(LNode));
if (L == NULL) return false;
L->next = L;
return true;
}
// 判断循环单链表是否为空
bool Empty(LinkList L) {
return L->next == L;
}
// 判断节点p是否为循环单链表的表尾节点
bool IsTail(LinkList L, LNode *p) {
return p->next = L;
}
循环双链表
#include <stdio.h>
#include <stdlib.h>
typedef struct DNode {
int data;
struct DNode *prior, *next;
} DNode, *DLinkList;
// 初始化循环双链表
bool InitDLinkList(DLinkList &L) {
L = (DNode *) malloc(sizeof(DNode));
if (L == NULL) return false;
L->prior = L; // 头结点的prior指向头结点
L->next = L; // 头结点的next指向头结点
return true;
}
// 判断循环双链表是否为空
bool Empty(DLinkList L) {
return L->next == L;
}
// 判断节点p是否为循环双链表的表尾节点
bool IsTail(DLinkList L, DNode *p) {
return p->next == L;
}
// 在p节点之后插入s节点
bool InsertNextDNode(DNode *p, DNode *s) {
if (p == NULL || s == NULL) return false;
s->next = p->next;
p->next->prior = s;
s->prior = p;
p->next = s;
return true;
}
// 删除p的后继节点
bool DeleteNextDNode(DNode *p) {
if (p == NULL) return false;
DNode *q = p->next;
p->next = q->next;
q->next->prior = p;
free(q);
return true;
}
7. 静态链表
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 10
typedef struct {
int data;
int next;
} SLinkList[MaxSize];
int main()
{
SLinkList a; // 声明一个静态链表
return 0;
}