注:并不是能在编译器运行的程序,写法上也有细节上的问题,仅供逻辑思路上的参考
一、线性表
顺序表
#define MaxSize 50
typedef int ElemType
//声明线性表的顺序存储类型
typedef struct
{ Elemtype data[MaxSize];
int length;
}SqList;
//建立顺序表
void CreateList(SqList *&L,ElemType a[],int n)
{ int i=0,k=0;
L = (SqList *)malloc(sizeof(SqList));
while(i<n){
L->data[k] = a[i];
k++;i++;
}
L->length = k;
}
//初始化线性表
void InitList(SqList *&L)
{
L - (SqList *)malloc(sizeof(SqList));
L ->length = 0;
} //本算法的时间复杂度为O(1)
//销毁线性表
void DestroyList(SqList *&L)
{
free(L);
}//本算法的时间复杂度为O(1)
//判断线性表是否为空
bool ListEmpty(SqList *L)
{
return(L->lenth==0);
}//本算法的时间复杂度为O(1)
//求线性表的长度
int ListLength(SqList *L)
{
return(L->length);
}//本算法的时间复杂度为O(1)
//输出线性表
void DispList(SqList *L)
{
for(int i=0;i<L->length;i++)
printf("%d",L->data[i]);
printf("\n");
}//本算法的时间复杂度为O(n)
/**
* 元素逆置,空间复杂度O(1)
*/
void Reverse(SqlList &L)
{
if (L.length <= 1)
{
return;
}
int i = 0;
int j = L.length - 1;
for (; i < j; i++, j--)
{
ElemType temp = L.data[i];
L.data[i] = L.data[j];
L.data[j] = temp;
}
}
/**
* 合并顺序表
*/
bool Merge(SqlList A, SqlList B, SqlList &C)
{
if (A.length + B.length > C.MaxSize)
{
return false;
}
int i = 0, j = 0, k = 0;
while (i < A.length && j < B.length)
{
if (A.data[i] < B.data[j])
{
C.data[k] = A.data[i];
k++;
i++;
}
else
{
C.data[k] = B.data[j];
k++;
j++;
}
}
while (i < A.length)
{
C.data[k] = A.data[i];
k++;
i++;
}
while (j < B.length)
{
C.data[k] = B.data[j];
k++;
j++;
}
C.length = k;
return true;
}
链表
#define ElemType int
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LNode
#include <LNode.h>
#include <stdio.h>
/**
* 头插法建立单链表
*/
void List_HeadInsert(LNode *&head, int a[], int n)
{
LNode *s;
int i;
head = (LNode *)malloc(sizeof(LNode));
head->next = NULL;
for (i = 0; i < n; i++)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = a[i];
s->next = head.next;
head.next = s;
}
}
/**
* 尾插法建立单链表
*/
void List_tailInsert(LNode *&head, int a[], int n)
{
LNode *s, *r;
int i;
head = (LNode *)malloc(sizeof(LNode));
head.next = NULL;
r = head;
for (i = 0; i < n; i++)
{
s = (LNode *)malloc(sizeof(LNode));
s->data = a[i];
r->next = s;
r = s;
}
r->next = NULL;
}
/**
* 合并链表
*/
void Merge(LNode *&A, LNode *&B, LNode *&C)
{
LNode *p = A->next;
LNode *q = B->next;
LNode *r = C;
r->next = NULL;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
r->next = p;
r = p;
p = p->next;
}
else
{
r->next = q;
r = q;
q = q->next;
}
}
// while (p != NULL)
// {
// r->next = p;
// r = p;
// p = p->next;
// }
// while (q != NULL)
// {
// r->next = q;
// r = q;
// q = q->next;
// }
// r->next = NULL;
// 将剩余部分直接连接即可
r->next = NULL;
if (p != NULL)
{
r->next = p;
}
if (q != NULL)
{
r->next = q;
}
}
二、树
typedef struct node
{
int data;
struct node *lchild;
struct node *rchild;
} BTNODE;
#include "btree.h"
#include <cstddef>
/**
* 构建二叉树
*/
void CreateBTree(BTNODE *b, char *str)
{
BTNODE *stack[10], *p;
int top = -1, k, j = 0;
char ch;
b = NULL;
ch = str[j];
while (ch != '\0')
{
switch (ch)
{
case '(': // 开始处理左孩子节点
top++;
stack[top] = p;
k = 1;
break;
case ')':
top--;
break;
case ',':
k = 2;
break;
default:
p = (BTNODE *)malloc(sizeof(BTNODE));
p->data = ch;
// 如果尚未建立根节点,则将p作为根节点
if (b == NULL)
{
b = p;
p->lchild = NULL;
p->rchild = NULL;
}
else
{
if (k == 1)
{
b->lchild = p;
}
else
{
b->rchild = p;
}
}
}
j++;
ch = str[j];
}
}
/***************递归写法******************/
/**
* 先序遍历二叉树
*/
void preOrder(BTNODE root)
{
if (root != NULL)
{
printf(root.data);
preOrder(root.lchild);
preOrder(root.rchild);
}
}
/**
* 中序遍历
*/
void InOrder(BTNODE root)
{
if (root != NULL)
{
InOrder(root.lchild);
printf(root.data);
InOrder(root.rchild);
}
}
/**
* 后续遍历
*/
void PostOrder(BTNODE root)
{
if (root != NULL)
{
PostOrder(root.lchild);
PostOrder(root.rchild);
printf(root.data);
}
}
/***************非递归写法******************/
/**
* 先序遍历二叉树
*/
void preOrder(BTNODE root)
{
InitStack(S); // 初始化一个栈
BTNODE *p = root;
while (p || !isEmpty(S))
{
if (p)
{
printf(p->data);
Push(S, p); // 入栈根节点,寻找左孩子节点
p = p->lchild;
}
else
{
Pop(S, p); // 不存在左孩子了,出栈该根节点,并访问右子树
p = p->rchild;
}
}
}
/**
* 中序遍历
*/
void InOrder(BTNODE root)
{
InitStack(S);
BTNODE *p = root;
while (p || !isEmpty(S))
{
if (p)
{
Push(p, S);
p = p->lchild; // 找到最左边的孩子
}
else
{
Pop(S, p); // 不存在叶子节点了,则出栈栈顶节点
printf(p->data);
p = p->rchild;
}
}
}
/**
* 后续遍历
*/
void PostOrder(BTNODE root)
{
InitStack(S);
BTNODE *p;
BTNODE *visitedNode;
while (p && !isEmpty(S))
{
if (p)
{
Push(S, p);
p = p->rchild; // 一路向左
}
else
{
GetTop(S, p); // 转向右边
if (p->rchild != NULL && p->rchild != visitedNode) // 不是刚刚出栈节点
{
p = p->rchild;
Push(S, p);
p = p->lchild; // 再次递归到最左
}
else
{
Pop(S, p);
printf(p->data);
visitedNode = p;
p = NULL; // 防止进入L156的左孩子节点继续入栈
}
}
}
}
/**
* 层次遍历
*/
void LevelOrder(BTNODE root)
{
InitQueue(Q);
BTNODE *p;
EnQueue(root);
while (!isEmpty(Q))
{
Dequeue(p);
printf(p->data);
if (p->lchild != NULL)
{
EnQueue(p->lchild);
}
if (p->rchild != NULL)
{
EnQueue(p->rchild);
}
}
}
int main(int argc, char const *argv[])
{
/* code */
return 0;
}
三、图
#define MaxVNum 100 // 顶点的最大数目
/**
* 邻接表
*/
typedef struct ArcNode
{
int adjvex; // 该弧指向的顶点
struct ArcNode *next; // 指向下一条弧
} ArcNode;
typedef struct VNode
{
VType data; // 顶点信息
ArcNode *first; // 指向第一条依附于该顶点的弧的指针
} VNode, AdjList[MaxVNum];
typedef struct
{
AdjList vertices; // 邻接表
int vNum, arcNum; // 图的定点数,弧数
} ALGraph;
/**
* 邻接矩阵
*/
#define MaxVNum 100 // 顶点的最大数目
typedef char VType;
typedef int EType;
typedef struct
{
VType V[MaxVNum]; // 顶点表
EType E[MaxVNum][MaxVNum]; // 邻接矩阵边表
int vNum, arcNum; // 顶点数量、边数
} MGraph;
#include <ALGraph.h>
#include <MGraph.h>
#include <stdio.h>
/**
* 图的广度优先遍历
*/
bool visited[MaxVNum]; // 顶点是否被访问的标记数组
void BFSTraverse(ALGraph G)
{
for (int i = 0; i < G.vNum; i++)
{
visited[i] = false // 将所有的顶点置为【未访问状态】
}
InitQueue(Q);
// 开始广度优先遍历
for (int i = 0; i < G.vNum; i++)
{
if (!visited[i])
{
BFS(G, i);
}
}
}
/**
* 广度优先遍历
*/
void BFS(ALGraph g, int vIndex)
{
printf(v);
visited[v] = true;
EnQueue(Q, v); // 入队
while (!isEmpty(Q))
{
DeQueue(Q, v); // 出队,并将其所有的关联顶点都入队
for (int i = FirstNeighbor(G, v); i >= 0; i = NextNeighbor(G, v))
{
if (!visited[i])
{
printf(i)
visited[i];
EnQueue(Q, i);
}
}
}
}
/**
* 深度优先遍历
*/
void DFSTraverse(ALGraph g)
{
for (int i = 0; i < G.vNum; i++)
{
visited[i] = false // 将所有的顶点置为【未访问状态】
}
InitQueue(Q);
// 开始深度优先遍历
for (int i = 0; i < G.vNum; i++)
{
if (!visited[i])
{
DFS(G, i);
}
}
}
void DFS(ALGraph g, int vIndex)
{
printf(vIndex);
visited[vIndex] = true;
for (int i = FirstNeighbor(G, v); i >= 0; i = NextNeighbor(G, v, i))
{
if (!visited[i])
{
DFS(g, i);
}
}
}
/**
* 邻接矩阵MGraph转邻接表AGLGraph
*/
void doTrans(ALGraph g, MGraph m)
{
g.arcNum = m.arcNum;
g.vNum = m.vNum;
// 初始化邻接表
for (int i = 0; i < g.vNum; i++)
{
g.vertices[i] = NULL;
}
ArcNode *p;
for (int i = 0; i < m.vNum; i++)
{
for (int j = 0; j < m.vNum; j++)
{
if (m.E[i][j] == 1)
{
p = (ArcNode *)malloc(sizeof(ArcNode));
// i,j之间有边,头插法,将该弧插入
p->adjvex = j;
p->next = g.vertices[i].first;
g.vertices[i].first = p;
}
}
}
}
/**
* 邻接表AGLGraph转邻接矩阵MGraph
*/
void doTrans(ALGraph g, MGraph m)
{
m.arcNum = g.arcNum;
m.vNum = g.vNum;
// 初始化邻接矩阵
for (int i = 0; i < m.vNum; i++)
{
for (int j = 0; j < m.vNum; j++)
{
m.E[i][j] == 0;
}
}
// 遍历邻接表
for (int i = 0; i < g.vNum; i++)
{
ArcNode *p = g.vertices[i].first;
while (p)
{
m.E[i][p->adjvex] = 1;
p = p->next;
}
}
}
/**
* 拓扑排序
*/
bool TopoLogicalSort(ALGraph g)
{
InitStack(S);
// 将所有度=0的节点入栈
for (int i = 0; i < g.vNum; i++)
{
if (inDegree(i) == 0)
{
Push(S, i);
}
}
int index = 0;
while (!isEmpty(S))
{
Pop(S, e);
// 出栈并记录并更新以该节点为起点的所有节点的入度
print[index++] = e;
ArcNode *p;
for (p = g.vertices[e].firstarc;; p = p->next)
{
if ((--inDegree[p.adjvex]) == 0)
{
Push(S, e);
}
}
}
if (index < g.vNum)
{
return false;
}
return true;
}
四、查找
typedef int ElemType;
typedef struct
{
ElemType *elem;
int length;
} SeqTable;
/**
* 顺序查找
*/
int Search_Seq(SeqTable table, ElemType key)
{
table[0] = key; // 哨兵,table[0]不存储数据
for (int i = table.length; i >= 0; --i)
{
if (table[i] == key)
{
return i;
}
}
}
/**
* 折半查找
*/
int Binary_Search(SeqTable table, ElemType key)
{
int low = 0, high = table.length - 1, mid;
while (low <= high)
{
mid = (high - low) / 2 + low; // 防止越界
if (table[mid] == key)
{
return mid;
}
else if (table[mid] > key)
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
return -1;
}
五、排序
typedef int ElemType;
/**
* 冒泡排序
*/
void BubbleSort(ElemType table[], int length)
{
bool change;
for (int i = 0; i < n - 1; i++)
{
change = false;
// 一趟冒泡排序
for (int j = n - 1; j > i; j--)
{
if (table[j] < table[j - 1])
{
swap(table[j - 1], table[j]);
change = true;
}
}
if (!change)
{
return;
}
}
}
/**
* 快排
*/
void QuickSort(ElemType table[], int low, int high)
{
if (low < high)
{
int pivot = Partition(table, low, high);
QuickSort(table, low, pivot - 1);
QuickSort(table, pivot + 1, high);
}
}
int Partition(ElemType table[], int low, int high)
{
ElemType pivot = table[low]; // 此处基准的选取,如果table基本有序,此时效率最低,可以选择随机数
while (low < high)
{
while (low < high && table[high] > pivot)
{
--high;
}
table[low] = table[high]; // pivot暂存table[low],
while (low < high && table[low] < pivot)
{
++low;
}
table[high] = table[low];
}
table[low] = pivot;
return low;
}
/**
* 简单选择排序
*/
void SelectSort(ElemType table[], int len)
{
for (int i = 0; i < len - 1; i++)
{
int min = i;
// 找到后面最小的数,更新min
for (int j = i + 1; j < len; j++)
{
if (table[j] < table[min])
{
min = j;
}
}
if (min != i)
{
swap(table[i], table[min]);
}
}
}