线性表
顺序表:参考C语言数组
单链表的存储结构
typedef struct _Node
{
ElemType data;
struct Node* next
}Node;
typedef struct
{
Node* root;
int length;
};
链表的逆置
Node* sort(Node* head)
{
Node* next = (Node*)malloc(sizeof(Node));
Node* pre = (Node*)malloc(sizeof(Node));
Node* current = head;
while(current != NULL)
{
next = current->next;
current->next=pre;
pre = current;
current = next;
}
head = pre;
return head;
}
两个递增单链表的二路归并(一元多项式相加)
Node* addToLink2(Node* head, int a, int b)
{
Node* p = (Node*)malloc(sizeof(Node));
Node* current = (Node*)malloc(sizeof(Node));
p->value1 = a;
p->value2 = b;
p->next = NULL;
if (b < head->value2)
{
p->next = head;
head = p;
}
current = head;
while (current->next != NULL && b >= current->next->value2)
{
current = current->next;
}
if (b == current->value2)
{
current->value1 += a;
}
else
{
p->next = current->next;
current->next = p;
}
return head;
}
栈
栈的存储结构及基本操作
typedef struct StackNode
{
ElementType* node;
struct StackNode* next;
} StackNode;
typedef struct Stack
{
StackNode* top;
} Stack;
//1、堆栈的初始化
void initStack(Stack* stack)
{
stack->top = NULL;
}
//2、判断堆栈是否为空
bool isEmpty(Stack* stack)
{
return stack->top == NULL;
}
//3、入栈
void push(Stack* stack, ElementType* node)
{
StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
newNode->node = node;
newNode->next = stack->top;
stack->top = newNode;
}
//4、出栈
ElementType* pop(Stack* stack)
{
if (stack->top == NULL)
{
return NULL;
}
ElementType* node = stack->top->node;
StackNode* temp = stack->top;
stack->top = stack->top->next;
free(temp);
return node;
}
堆栈实现进制转换
int change(int number)
{
SqStack s;
InitStack(&s);
while (number != 0)
{
push(&s, number % 2);
number = number / 2;
}
int result = 0;
while (s.top != s.base)
{
result = result * 10 + pop(&s);
}
return result;
}
表达式转逆波兰式
int priority(char a)
{
if (a == '+' || a == '-')
{
return 1;
}
else if (a == '*' || a == '/')
{
return 2;
}
else
return 0;
}
void infixToPostfix(char* infix,char* postfix)
{
char stack[MAX_SIZE];
char temp;
int top = -1;
int i, j = 0;
for (i = 0; infix[i] != '\0'; i++)
{
temp = infix[i];
if (temp >= 'a' && temp <= 'z')
{
postfix[j++] = temp;
}
else if (temp == '(')
{
stack[++top] = temp;
}
else if (temp == ')')
{
while (top != -1 && stack[top] != '(')
{
postfix[j++] = stack[top--];
}
top--; // 弹出 '('
}
else
{
while (top != -1 && priority(stack[top]) >= priority(temp))
{
postfix[j++] = stack[top--];
}
stack[++top] = temp;
}
}
while (top != -1) {
postfix[j++] = stack[top--];
}
postfix[j] = '\0';
}
计算逆波兰式
int calculate(char* Postfix)
{
int num1, num2, i=0;
Stack stack;
initstack(&stack);
while (Postfix[i] != '\0')
{
if (Postfix[i] >= '0' && Postfix[i] <= '9')
{
push(&stack,Postfix[i] - '0'); // 将字符转换为整数并入栈
}
else
{
num1 = pop(&stack); // 先取出第二个操作数
num2 = pop(&stack); // 再取出第一个操作数
switch (Postfix[i])
{
case '+':
push(&stack, num1 + num2);
break;
case '-':
push(&stack, num2 - num1);
break;
case '*':
push(&stack, num1 * num2);
break;
case '/':
push(&stack, num2 / num1);
break;
}
}
i++;
}
return top(&stack);
}
八皇后问题
int examine(int board[N][N], int row, int col)
{
int i = 0;
// 检查皇后所在列是否有其他皇后
for (i = 0; i < N; i++)
{
if (board[i][col]) return 0;
}
// 检查左斜线是否有其他皇后
for (i = 0; row - i >= 0 && col - i >= 0; i++)
{
if (board[row - i][col - i]) return 0;
}
// 检查右斜线是否有其他皇后
for (i = 0; row - i >= 0 && col + i < N; i++)
{
if (board[row - i][col + i]) return 0;
}
return 1;
}
int Queen(int board[N][N], int row, int solutions)
{
int col = 0;
int i, j;
for (col = 0; col < N; col++)
{
if (examine(board, row, col))
{
board[row][col] = 1;
solutions = Queen(board, row + 1, solutions);
//开始递归直到找出一种solution
board[row][col] = 0;
//找到或没找到都回溯到原来的状态开始找该行的下一列
}
}
if (row == N)
{
solutions++;
printf("第%d种解法:\n", solutions);
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
printf("%d ", board[i][j]);
}
printf("\n");
}
printf("\n");
return solutions;
}
return solutions;
}
队列
队列的存储结构及基本操作
typedef struct queue
{
ElementType data[MAXSIZE];
int front,rear;
} Queue;
//1、队列的初始化
void initQueuek(Queue* q)
{
q->front = q->rear = 0;
}
//2、判断队列是否为空
bool isEmpty(Queue* q)
{
return q->front == q->rear;
}
//3、入队(队尾)
void push(Queue* q, ElementType data)
{
q->data[q->rear] = data;
q->rear++;
}
//4、出队(队头)
ElementType* pop(Queue* q)
{
if (q->front == NULL)
{
return NULL;
}
ElementType data = q->data[q->front];
q->front++;
return data;
}
数组
三元组存储结构及基本操作
//三元组定义
typedef struct
{
int ElementsNum;
Element data[MATRIX_SIZE * MATRIX_SIZE];
} Triple;
//三元组的初始化
void inittriple(Triple* triple)
{
triple->ElementsNum = 0;
}
//向三元组中添加元素
Triple addtotriple(Triple* triple, int row, int col, int value)
{
triple->data[triple->ElementsNum].row = row;
triple->data[triple->ElementsNum].col = col;
triple->data[triple->ElementsNum].value = value;
triple->ElementsNum++;
return *triple;
}
//在三元组第i个位置前面插入一个元素
Triple insert(Triple t, Element data, int i)
{
int j;
for (j = t.ElementsNum; j >= i; j--)
{
t.data[j+1] = t.data[j];
}
t.data[i] = data;
t.ElementsNum++;
return t;
}
//删除三元组中的第i个元素
Triple delete(Triple t, int i)
{
int j;
for (j = i; j < t.ElementsNum; j++)
{
t.data[j] = t.data[j + 1];
}
t.ElementsNum--;
return t;
}
三元组矩阵转置
void presentTransposition(Triple* triple)
{
int i, j;
int temp;
Element data;
for (i = 0; i < triple->ElementsNum; i++)
{
temp = triple->data[i].row;
triple->data[i].row = triple->data[i].col;
triple->data[i].col = temp;
}
for (i = 0; i < triple->ElementsNum; i++)
{
for (j = i + 1; j < triple->ElementsNum; j++)
{
if (triple->data[j].row < triple->data[i].row)
{
data = triple->data[j];
triple->data[j] = triple->data[i];
triple->data[i] = data;
}
}
}
}
三元组矩阵相乘
Triple calculate(Triple t1, Triple t2)
{
int i, j;
Triple result;
initTriple(&result);
for (i = 0; i < t1.ElementNum; i++)
{
for (j = 0; j < t2.ElementNum; j++)
{
if (t2.data[j].row == t1.data[i].col)
{
result.data[result.ElementNum].row = t1.data[i].row;
result.data[result.ElementNum].col = t2.data[j].col;
result.data[result.ElementNum].value = t1.data[i].value * t2.data[j].value;
result.ElementNum++;
}
}
}
return result;
}
三元组的二路归并(矩阵相加)
Triple merge(Triple t1, Triple t2)
{
int i, j;
int flag;
for (i = 0; i < t2.ElementsNum; i++)
{
flag = 0;
for (j = 0; j < t1.ElementsNum; j++)
{
if (t2.data[i].row < t1.data[j].row)
{
flag = 1;
t1 = insert(t1, t2.data[i], j);
break;
}
else if (t2.data[i].row == t1.data[j].row)
{
if (t2.data[i].col < t1.data[j].col)
{
flag = 1;
t1 = insert(t1, t2.data[i], j);
break;
}
else if (t2.data[i].col == t1.data[j].col)
{
flag = 1;
t1.data[j].value += t2.data[i].value;
if (t1.data[j].value == 0)
{
t1 = delete(t1, j);
}
break;
}
else
continue;
if (!flag)
{
t1 = insert(t1, t2.data[i], j + 1);
}
}
}
if(!flag)
{
t1.data[t1.ElementsNum] = t2.data[i];
t1.ElementsNum++;
}
}
return t1;
}
串
BF暴力匹配算法
int BF_match(strLink* head, char subStr[])
{
int length = strlen(subStr);
int i;
int index = 0;
strLink* current = head;
while (current != NULL)
{
int flag = 1;
strLink* back = current;
for (i = 0; i < length && back!= NULL; i++)
{
if (back->ch == subStr[i])
{
back = back->next;
}
else
{
flag = 0;
break;
}
}
if (flag)
{
return index;
}
current = current->next;
index++;
}
return 0;
}
KMP算法
int KMP_match(strLink* head, char subStr[])
{
//1、求subStr的next数组
int length = strlen(subStr);
int next[10];
next[0] = 0;
for (int j = 1; j < length; j++)
{
int index = next[j - 1];
if (subStr[j] == subStr[index])
{
next[j] = next[j - 1] + 1;
}
else
{
while (index > 0 && subStr[j] != subStr[index])
{
index = next[index - 1];
}
if (subStr[j] == subStr[index])
{
index++;
}
next[j] = index;
}
}
for(int k=0;k<length;k++)
{
printf("%d ",next[k]);
}
//2、与串进行匹配
strLink* current = head;
int index = 0;
int k = 0;
while (current != NULL)
{
if (current->ch == subStr[k])
{
current = current->next;
index++;
k++;
}
else
{
if (k == 0)
{
current = current->next;
index++;
}
else
{
k = next[k - 1];
}
}
if (k == length)
{
return index - length;
}
}
return 0;
}
树与二叉树
树的存储结构
typedef struct TreeNode
{
int data;
struct TreeNode* parent;
} TreeNode;
typedef struct Tree
{
TreeNode tns[MAX_SIZE];
int r, n;
} Tree;
二叉树的存储结构
typedef struct BiTreeNode
{
int data;
struct BiTreeNode* leftChild;
struct BiTreeNode* rightBrother;
} BiTreeNode;
typedef struct BiTree
{
BiTreeNode btns[MAX_SIZE];
int r, n;
} BiTree;
树转二叉树
void findChild(BiTreeNode* root, Tree tree)
{
BiTreeNode* currentChild = NULL;
for (int i = 0; i < tree.n; i++)
{
if (tree.tns[i].parent && tree.tns[i].parent->data == root->data)
{
BiTreeNode* newChild = &bitree.btns[i];
if (currentChild == NULL)
{
root->leftChild = newChild;
}
else
{
currentChild->rightBrother = newChild;
}
currentChild = newChild;
findChild(currentChild, tree);
}
}
}
BiTree treeToBiTree(Tree tree)
{
bitree.r = 0;
bitree.n = tree.n;
for (int i = 0; i < bitree.n; i++)
{
bitree.btns[i].data = tree.tns[i].data;
bitree.btns[i].leftChild = NULL;
bitree.btns[i].rightBrother = NULL;
}
BiTreeNode* root = &bitree.btns[0];
findChild(root, tree);
return bitree;
}
二叉树转树
void addChild(TreeNode* parent, BiTreeNode* child, Tree* tree2)
{
tree2->tns[tree2->n].data = child->data;
tree2->tns[tree2->n].parent = parent;
tree2->n++;
if (child->leftChild != NULL)
{
addChild(&tree2->tns[tree2->n - 1], child->leftChild, tree2);
}
if (child->rightBrother != NULL)
{
addChild(parent, child->rightBrother, tree2);
}
}
Tree biTreeToTree(BiTree bitree)
{
tree2.r = 0;
tree2.n = 0;
addChild(NULL, &bitree.btns[0], &tree2);
return tree;
}
先序、中序遍历法确定二叉树
treeNode* createTree(char* pre, char* in, int start, int end)
{
static int preIndex = 0;
if (start > end)
{
return NULL;
}
treeNode* root = (treeNode*)malloc(sizeof(treeNode));
root->ch = pre[preIndex++];
root->lChild = root->rChild = NULL;
if (start == end)
{
return root;
}
int inIndex;
for (int i = start; i <= end; i++)
{
if (in[i] == root->ch)
{
inIndex = i;
break;
}
}
root->lChild = createTree(pre, in, start, inIndex - 1);
root->rChild = createTree(pre, in, inIndex + 1, end);
return root;
}
二叉树非递归遍历(堆栈、队列)
堆栈:先序为例
void PreOrderTraversal_stack(BiTreeNode* root)
{
if (root == NULL)
{
return;
}
Stack stack;
initStack(&stack);
BiTreeNode* current = root;
while (current != NULL || !isEmpty(&stack))
{
while (current != NULL)
{
printf("%d ", current->data);
push(&stack, current);
current = current->leftChild;
}
if (!isEmpty(&stack))
{
current = pop(&stack);
current = current->rightBrother;
}
}
}
队列:层次遍历法
void levelOrderTraversal(BiTreeNode* root)
{
if (root == NULL)
{
return;
}
QueueNode* queue = NULL;
enqueue(&queue, root);
while (queue != NULL)
{
BiTreeNode* node = dequeue(&queue);
printf("%d ", node->data);
if (node->leftChild != NULL)
{
enqueue(&queue, node->leftChild);
}
if (node->rightBrother != NULL)
{
enqueue(&queue, node->rightBrother);
}
}
}
创建哈夫曼树
int findMin(hTreeNode* hfTree, int n)
{
int target = -1;
unsigned int fMin = MIN;
for (int i = 0; i < n; i++)
{
if (hfTree[i].weight < fMin && hfTree[i].parent == -1)
{
fMin = hfTree[i].weight;
target = i;
}
}
hfTree[target].parent = 0;
return target;
}
hTreeNode* createHfTree(char* filename, int* n)
{
FILE* fp = fopen(filename, "r");
if (fp == NULL)
{
printf("文件打开错误");
return NULL;
}
fscanf(fp, "%d\n", &(*n));
hTreeNode* hfTree = (hTreeNode*)malloc((2 * (*n) - 1) * sizeof(hTreeNode));
memset(hfTree, 0, (2 * (*n) - 1) * sizeof(hTreeNode));
for (int i = 0; i < (*n); i++)
{
char ch;
int weight;
fscanf(fp, " %c %d\n", &ch, &weight);
hfTree[i].c = ch;
hfTree[i].weight = weight;
hfTree[i].parent = hfTree[i].lChild = hfTree[i].rChild = -1;
}
fclose(fp);
for (int i = *n; i < (2 * (*n) - 1); i++)
{
int m1 = findMin(hfTree, i);
int m2 = findMin(hfTree, i);
hfTree[i].parent = -1;
hfTree[i].lChild = m1;
hfTree[i].rChild = m2;
hfTree[i].weight = hfTree[m1].weight + hfTree[m2].weight;
hfTree[i].c = ' ';
hfTree[m1].parent = hfTree[m2].parent = i;
}
return hfTree;
}
图
图的存储结构
邻接矩阵表示
typedef struct MGraph_adjM
{
char data[MAX_NUM];//顶点
int arc[MAX_NUM][MAX_NUM];//邻接矩阵
int vexnum, arcnum;//当前顶点数和边数
}MGraph_adjM;
邻接表表示
typedef struct ArcNode
{
int adjvex;
struct ArcNode* nextarc;
}ArcNode;//边结点结构
typedef struct VNode
{
char data;
ArcNode* firstArc;
}VNode;//顶点结点结构
typedef struct MGraph_adjL
{
VNode adjList[MAX_NUM];
int vexnum, arcnum;
}MGraph_adjL;
邻接矩阵转邻接表
MGraph_adjL adjMtoList(MGraph_adjM g)
{
MGraph_adjL l;
l.vexnum = g.vexnum;
l.arcnum = g.arcnum;
for (int k = 0; k < g.vexnum; k++)
{
l.adjList[k].data = g.data[k];
l.adjList[k].firstArc = NULL;
}
for (int i = 0; i < l.vexnum; i++)
{
for (int j = 0; j < l.vexnum; j++)
{
if (g.arc[i][j] == 1)
{
ArcNode* arc = (ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex = j;
arc->nextarc = NULL;
if (l.adjList[i].firstArc == NULL)
{
l.adjList[i].firstArc = arc;
}
else
{
ArcNode* current = l.adjList[i].firstArc;
while (current->nextarc != NULL)
{
current = current->nextarc;
}
current->nextarc = arc;
}
}
}
}
return l;
}
邻接表转关联矩阵
MGraph_relaM adjLtoRelaM(MGraph_adjL l)
{
MGraph_relaM m;
m.row = l.vexnum;
m.col = l.arcnum;
for (int i = 0; i < m.row; i++)
{
for (int j = 0; j < m.col; j++)
{
m.RelaM[i][j] = 0;
}
}
int arc = 0;L
for (int i = 0; i < m.row; i++)
{
ArcNode* current = l.adjList[i].firstArc;
while (current != NULL)
{
m.RelaM[i][arc] = 1;
m.RelaM[current->adjvex][arc++] = -1;
current = current->nextarc;
}
}
return m;
}
关联矩阵转邻接矩阵
MGraph_adjM RelaMtoAdjM(MGraph_relaM m)
{
MGraph_adjM g2;
g2.vexnum = m.row;
g2.arcnum = m.col;
for (int i = 0; i < m.col; i++)
{
g2.data[i] = 'A' + i;
for (int j = 0; j < m.col; j++)
{
g2.arc[i][j] = 0;
}
int row, col = 0;
for (int k = 0; k < m.row; k++)
{
if (m.RelaM[k][i] == 1)
{
row = k;
}
if (m.RelaM[k][i] == -1)
{
col = k;
}
}
g2.arc[row][col] = 1;
}
return g2;
}
图的遍历
DFS堆栈遍历
void DFS_stack(VNode anode, MGraph_adjL* l)
{
VNode* stack = (VNode*)malloc(l->vexnum * sizeof(VNode));
int top = -1;
stack[++top] = anode;
while (top != -1)
{
//1、弹出栈顶
ArcNode* p = stack[top].firstArc;
printf("%c ", stack[top].data);
top--;
//2、将未访问的所有邻接顶点压入栈
while (p != NULL)
{
if (!l->adjList[p->adjvex].info)
{
l->adjList[p->adjvex].info = 1;
stack[++top] = l->adjList[p->adjvex];
}
p = p->nextarc;
}
}
free(stack);
}
BFS队列遍历
void BFS(VNode anode, MGraph_adjL* l)
{
int front = 0, rear = 0;//front队头,rear队尾
VNode* queue=(VNode*)malloc(l->vexnum*sizeof(VNode));
queue[rear++] = anode;
while (front != rear)
{
VNode node = queue[front++];
node.info = 1;
printf("%c ", node.data);
ArcNode* p = node.firstArc;
while (p != NULL)
{
if (!l->adjList[p->adjvex].info)
{
queue[rear++] = l->adjList[p->adjvex];
l->adjList[p->adjvex].info = 1;
}
p = p->nextarc;
}
}
free(queue);
}
最小生成树
Prim算法(算法以人名命名肯定重要)
void Prim(MGraph g)
{
int lowcost[MAX_NUM]; // 存储顶点到集合U的最短边权值
int adjvex[MAX_NUM]; // 存储最短边终点的下标
for (int i = 1; i < g.vexnum; i++)
{
lowcost[i] = g.arc[0][i];
adjvex[i] = 0;
}
for (int i = 1; i < g.vexnum; i++)
{
int min = INFINITY;
int k = 0;
for (int j = 1; j < g.vexnum; j++)
{
if (lowcost[j] != 0 && lowcost[j] < min)
{
min = lowcost[j];
k = j;
}
}// 找出剩余顶点中权值最小的边
printf("%c -> %c : %d\n", g.data[adjvex[k]], g.data[k], min); // 打印最小生成树的边和权值
lowcost[k] = 0; // 将该顶点加入集合U
// 更新lowcost和adjvex数组
for (int j = 1; j < g.vexnum; j++)
{
if (lowcost[j] != 0 && g.arc[k][j] < lowcost[j])
{
lowcost[j] = g.arc[k][j];
adjvex[j] = k;
}
}
}
}
Kruskal算法
void Kruskal(MGraph g)
{
int parent[MAX_NUM];//用于标记顶点所在集合
for (int i = 0; i < g.vexnum; i++)
{
parent[i] = i;
}//最初每个顶点分别属于不同集合
int edgeCount = 0;
while (edgeCount < g.vexnum - 1)//最小生成树的边数为顶点数减一
{
int MIN = INFINITY;
int row = 0, col = 0;
for (int i = 0; i < g.vexnum; i++)
{
for (int j = i + 1; j < g.vexnum; j++)
{
if (g.arc[i][j] < MIN && g.arc[i][j] != 0)
{
MIN = g.arc[i][j];
row = i;
col = j;
}
}
}//遍历邻接矩阵找到权重值最小的边
if (parent[row] != parent[col])
{
printf("%c -> %c : %d\n", g.data[row], g.data[col], MIN);
for (int i = 0; i < g.vexnum; i++)
{
if (parent[i] == parent[col])
{
parent[i] = parent[row];
}
}//合并顶点集
edgeCount++;
}
g.arc[row][col] = g.arc[col][row] = 0; // 标记已加入最小生成树
}
}
最短路径Dijkstra算法
void Dijkstra(MGraph g)
{
int dist[MAX_NUM];
int pre[MAX_NUM];
for (int k = 0; k < g.vexnum; k++)
{
dist[k] = g.arc[0][k];
pre[k] = -1;
}
for (int i = 0; i < g.vexnum; i++)
{
int MIN = INFINITY;
int m = -1;
for (int j = 1; j < g.vexnum; j++)
{
if (dist[j] < MIN && pre[j] == -1)
{
MIN = dist[j];
m = j;
}
}
if (m == -1)
{
break;
}
pre[m] = 0;
for (int j = 0; j < g.vexnum; j++)
{
int temp_distance = dist[m] + g.arc[m][j];
if (g.arc[m][j] != 0 && temp_distance < dist[j])
{
dist[j] = temp_distance;
pre[j] = m;
m = j;
}
}
}
printPath(g, dist, pre);
}
查找
顺序查找
int Sequential_Search(searchList alist,int key){
alist.data[0]=key;
int i=alist.length;
while(alist.data[i]!=key){
i--;
}
return i;
}
折半查找
int Binary_Search(searchList alist,int key,int start,int end){
if(start>end){
return 0;
}
int mid=start+(end-start)/2;
if(alist.data[mid]==key){
return mid;
}
else if(alist.data[mid]>key){
return Binary_Search(alist,key,start,mid-1);
}
else{
return Binary_Search(alist,key,mid+1,end);
}
}
排序
希尔排序
searchList shell_Sort(searchList alist)
{
/*gap是设置的查找间隔*/
int gap[4] = { 7,5,3,1 };
for (int k = 0; k < 4; k++)
{
int delta = gap[k];
for (int i = delta; i < alist.length; i++)
{
int temp = alist.data[i];
int j;
for (j = i; j >= delta && alist.data[j - delta] > temp; j -= delta)
{
alist.data[j] = alist.data[j - delta];
}
alist.data[j] = temp;
}
}
return alist;
}
快速排序
searchList quick_Sort(searchList alist, int start, int end)
{
int pivot = alist.data[start];
int low = start, high = end;
if (low >= high)
{
return alist;
}
while (low < high)
{
while (low < high && alist.data[high] >= pivot)
{
high--;
}
alist.data[low] = alist.data[high];
while (low < high && alist.data[low] <= pivot)
{
low++;
}
alist.data[high] = alist.data[low];
}
alist.data[low] = pivot;
//至此完成第一趟排序
quick_Sort(alist, start, low - 1);
quick_Sort(alist, low + 1, end);
return alist;
}
堆排序
基数排序