数据结构网课代码整理
注:以下代码基于 C 语言实现,通用数据类型 ElemType 统一定义为 int。
一、线性表
1. 顺序表
1.1 顺序表结构体定义(静态+动态)
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> typedef int ElemType;#define MaxSize 50 typedef struct { ElemType data[MaxSize]; int length; } SqList; #define InitSize 50 typedef struct { ElemType *data; int MaxSize; int length; } SeqList;
1.2 顺序表核心操作
void InitSqList (SqList &L) { L.length = 0 ; } bool InitSeqList (SeqList &L) { L.data = (ElemType *)malloc (sizeof (ElemType) * InitSize); if (L.data == NULL ) return false ; L.MaxSize = InitSize; L.length = 0 ; return true ; } bool ListInsert (SqList &L, int i, ElemType e) { if (i < 1 || i > L.length + 1 ) return false ; if (L.length >= MaxSize) return false ; for (int j = L.length; j >= i; j--) { L.data[j] = L.data[j - 1 ]; } L.data[i - 1 ] = e; L.length++; return true ; } bool ListDelete (SqList &L, int i, ElemType &e) { if (i < 1 || i > L.length) return false ; e = L.data[i - 1 ]; for (int j = i; j < L.length; j++) { L.data[j - 1 ] = L.data[j]; } L.length--; return true ; } ElemType GetElem (SqList L, int i) { if (i < 1 || i > L.length) { printf ("位置不合法\n" ); exit (1 ); } return L.data[i - 1 ]; } int LocateElem (SqList L, ElemType e) { for (int i = 0 ; i < L.length; i++) { if (L.data[i] == e) { return i + 1 ; } } return 0 ; } bool MergeSqList (SqList A, SqList B, SqList &C) { if (A.length + B.length > 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++]; } else { C.data[k++] = B.data[j++]; } } while (i < A.length) { C.data[k++] = A.data[i++]; } while (j < B.length) { C.data[k++] = B.data[j++]; } C.length = k; return true ; }
2. 链表
2.1 单链表结构体定义
typedef struct LNode { ElemType data; struct LNode *next ; } LNode, *LinkList;
2.2 单链表核心操作
bool InitLinkList (LinkList &L) { L = (LNode *)malloc (sizeof (LNode)); if (L == NULL ) return false ; L->next = NULL ; return true ; } LNode *GetElemLinkList (LinkList L, int i) { if (i < 0 ) return NULL ; LNode *p = L; int j = 0 ; while (p != NULL && j < i) { p = p->next; j++; } return p; } LNode *LocateElemLinkList (LinkList L, ElemType e) { LNode *p = L->next; while (p != NULL && p->data != e) { p = p->next; } return p; } bool ListInsertLinkList (LinkList &L, int i, ElemType e) { LNode *p = GetElemLinkList(L, i - 1 ); if (p == NULL ) return false ; LNode *s = (LNode *)malloc (sizeof (LNode)); if (s == NULL ) return false ; s->data = e; s->next = p->next; p->next = s; return true ; } bool ListDeleteLinkList (LinkList &L, int i, ElemType &e) { LNode *p = GetElemLinkList(L, i - 1 ); if (p == NULL || p->next == NULL ) return false ; LNode *q = p->next; e = q->data; p->next = q->next; free (q); return true ; }
2.3 双链表
typedef struct DNode { ElemType data; struct DNode *prior ; struct DNode *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 DLinkListInsertAfter (DNode *p, DNode *s) { if (p == NULL || s == NULL ) return false ; s->next = p->next; if (p->next != NULL ) { p->next->prior = s; } s->prior = p; p->next = s; return true ; } bool DLinkListDeleteNext (DNode *p) { if (p == NULL || p->next == NULL ) return false ; DNode *q = p->next; p->next = q->next; if (q->next != NULL ) { q->next->prior = p; } free (q); return true ; }
2.4 循环单链表(带头结点)
bool InitCircLinkList (LinkList &L) { L = (LNode *)malloc (sizeof (LNode)); if (L == NULL ) return false ; L->next = L; return true ; } bool CircLinkListEmpty (LinkList L) { return L->next == L; }
二、栈和队列
1. 栈
1.1 顺序栈
#define StackMaxSize 50 typedef struct { ElemType data[StackMaxSize]; int top; } SqStack; void InitSqStack (SqStack &S) { S.top = -1 ; } bool StackEmpty (SqStack S) { return S.top == -1 ; } bool Push (SqStack &S, ElemType x) { if (S.top == StackMaxSize - 1 ) return false ; S.data[++S.top] = x; return true ; } bool Pop (SqStack &S, ElemType &x) { if (StackEmpty(S)) return false ; x = S.data[S.top--]; return true ; } bool GetTop (SqStack S, ElemType &x) { if (StackEmpty(S)) return false ; x = S.data[S.top]; return true ; }
1.2 链栈
typedef struct LinkNode { ElemType data; struct LinkNode *next ; } LinkNode, *LiStack; void InitLiStack (LiStack &S) { S = NULL ; } bool LiStackEmpty (LiStack S) { return S == NULL ; } bool LiStackPush (LiStack &S, ElemType x) { LinkNode *p = (LinkNode *)malloc (sizeof (LinkNode)); if (p == NULL ) return false ; p->data = x; p->next = S; S = p; return true ; } bool LiStackPop (LiStack &S, ElemType &x) { if (LiStackEmpty(S)) return false ; LinkNode *p = S; x = p->data; S = S->next; free (p); return true ; }
2. 队列
2.1 循环队列(顺序存储)
#define QueueMaxSize 50 typedef struct { ElemType data[QueueMaxSize]; int front; int rear; } SqQueue; void InitSqQueue (SqQueue &Q) { Q.front = Q.rear = 0 ; } bool QueueEmpty (SqQueue Q) { return Q.front == Q.rear; } bool QueueFull (SqQueue Q) { return (Q.rear + 1 ) % QueueMaxSize == Q.front; } bool EnQueue (SqQueue &Q, ElemType x) { if (QueueFull(Q)) return false ; Q.data[Q.rear] = x; Q.rear = (Q.rear + 1 ) % QueueMaxSize; return true ; } bool DeQueue (SqQueue &Q, ElemType &x) { if (QueueEmpty(Q)) return false ; x = Q.data[Q.front]; Q.front = (Q.front + 1 ) % QueueMaxSize; return true ; } bool GetHead (SqQueue Q, ElemType &x) { if (QueueEmpty(Q)) return false ; x = Q.data[Q.front]; return true ; } int QueueLength (SqQueue Q) { return (Q.rear - Q.front + QueueMaxSize) % QueueMaxSize; }
2.2 链队列
typedef struct LinkNode { ElemType data; struct LinkNode *next ; } LinkNode; typedef struct { LinkNode *front, *rear; } LinkQueue; void InitLinkQueue (LinkQueue &Q) { Q.front = Q.rear = (LinkNode *)malloc (sizeof (LinkNode)); if (Q.front == NULL ) exit (1 ); Q.front->next = NULL ; } bool LinkQueueEmpty (LinkQueue Q) { return Q.front == Q.rear; } bool EnLinkQueue (LinkQueue &Q, ElemType x) { LinkNode *p = (LinkNode *)malloc (sizeof (LinkNode)); if (p == NULL ) return false ; p->data = x; p->next = NULL ; Q.rear->next = p; Q.rear = p; return true ; } bool DeLinkQueue (LinkQueue &Q, ElemType &x) { if (LinkQueueEmpty(Q)) return false ; LinkNode *p = Q.front->next; x = p->data; Q.front->next = p->next; if (Q.rear == p) { Q.rear = Q.front; } free (p); return true ; }
三、树和二叉树
1. 二叉树结构体(二叉链表)
typedef struct BiTNode { ElemType data; struct BiTNode *lchild , *rchild ; } BiTNode, *BiTree;
2. 二叉树遍历(递归实现)
void PreOrder (BiTree T) { if (T != NULL ) { printf ("%d " , T->data); PreOrder(T->lchild); PreOrder(T->rchild); } } void InOrder (BiTree T) { if (T != NULL ) { InOrder(T->lchild); printf ("%d " , T->data); InOrder(T->rchild); } } void PostOrder (BiTree T) { if (T != NULL ) { PostOrder(T->lchild); PostOrder(T->rchild); printf ("%d " , T->data); } } void LevelOrder (BiTree T) { LinkQueue Q; InitLinkQueue(Q); if (T != NULL ) { EnLinkQueue(Q, T->data); Q.front->next->data = T->data; BiTNode *p = T; EnLinkQueue(Q, p->data); } while (!LinkQueueEmpty(Q)) { BiTNode *p; ElemType x; DeLinkQueue(Q, x); printf ("%d " , x); if (p->lchild != NULL ) { EnLinkQueue(Q, p->lchild->data); } if (p->rchild != NULL ) { EnLinkQueue(Q, p->rchild->data); } } }
3. 二叉排序树
bool BST_Insert (BiTree &T, ElemType key) { if (T == NULL ) { T = (BiTNode *)malloc (sizeof (BiTNode)); T->data = key; T->lchild = T->rchild = NULL ; return true ; } else if (key == T->data) { return false ; } else if (key < T->data) { return BST_Insert(T->lchild, key); } else { return BST_Insert(T->rchild, key); } } void CreateBST (BiTree &T, ElemType key[], int n) { T = NULL ; for (int i = 0 ; i < n; i++) { BST_Insert(T, key[i]); } } BiTNode *BST_Search (BiTree T, ElemType key) { if (T == NULL || T->data == key) { return T; } else if (key < T->data) { return BST_Search(T->lchild, key); } else { return BST_Search(T->rchild, key); } }
4. 哈夫曼树(构造与编码)
typedef struct { ElemType weight; int parent, lchild, rchild; } HTNode, *HuffmanTree; typedef char **HuffmanCode;void Select (HuffmanTree HT, int n, int &s1, int &s2) { int min1 = INT_MAX, min2 = INT_MAX; s1 = s2 = 0 ; for (int i = 1 ; i <= n; i++) { if (HT[i].parent == 0 ) { if (HT[i].weight < min1) { min2 = min1; s2 = s1; min1 = HT[i].weight; s1 = i; } else if (HT[i].weight < min2) { min2 = HT[i].weight; s2 = i; } } } } void CreateHuffmanTree (HuffmanTree &HT, int n) { if (n <= 1 ) return ; int m = 2 * n - 1 ; HT = (HuffmanTree)malloc ((m + 1 ) * sizeof (HTNode)); for (int i = 1 ; i <= n; i++) { HT[i].parent = 0 ; HT[i].lchild = 0 ; HT[i].rchild = 0 ; printf ("输入第%d个叶子结点的权重:" , i); scanf ("%d" , &HT[i].weight); } for (int i = n + 1 ; i <= m; i++) { HT[i].parent = 0 ; HT[i].lchild = 0 ; HT[i].rchild = 0 ; HT[i].weight = 0 ; } for (int i = n + 1 ; i <= m; i++) { int s1, s2; Select(HT, i - 1 , s1, s2); HT[s1].parent = i; HT[s2].parent = i; HT[i].lchild = s1; HT[i].rchild = s2; HT[i].weight = HT[s1].weight + HT[s2].weight; } } void CreateHuffmanCode (HuffmanTree HT, HuffmanCode &HC, int n) { HC = (HuffmanCode)malloc ((n + 1 ) * sizeof (char *)); char *cd = (char *)malloc (n * sizeof (char )); cd[n - 1 ] = '\0' ; for (int i = 1 ; i <= n; i++) { int start = n - 1 ; int c = i; int f = HT[i].parent; while (f != 0 ) { start--; if (HT[f].lchild == c) { cd[start] = '0' ; } else { cd[start] = '1' ; } c = f; f = HT[f].parent; } HC[i] = (char *)malloc ((n - start) * sizeof (char )); strcpy (HC[i], &cd[start]); } free (cd); }
四、图
1. 图的存储结构
1.1 邻接矩阵(无向图/有向图/带权图)
#define MaxVertexNum 100 #define INF 32767 typedef struct { char Vex[MaxVertexNum]; int Edge[MaxVertexNum][MaxVertexNum]; int vexnum, arcnum; } MGraph; void InitMGraph (MGraph &G, int n) { G.vexnum = n; G.arcnum = 0 ; for (int i = 0 ; i < G.vexnum; i++) { G.Vex[i] = 'A' + i; } for (int i = 0 ; i < G.vexnum; i++) { for (int j = 0 ; j < G.vexnum; j++) { G.Edge[i][j] = (i == j) ? 0 : INF; } } } void AddUndirEdge (MGraph &G, int v1, int v2, int w) { G.Edge[v1][v2] = w; G.Edge[v2][v1] = w; G.arcnum++; } void AddDirEdge (MGraph &G, int v1, int v2, int w) { G.Edge[v1][v2] = w; G.arcnum++; }
1.2 邻接表(无向图/有向图)
typedef struct ArcNode { int adjvex; int weight; struct ArcNode *nextarc ; } ArcNode; typedef struct VNode { char data; ArcNode *firstarc; } VNode, AdjList[MaxVertexNum]; typedef struct { AdjList vertices; int vexnum, arcnum; } ALGraph; void InitALGraph (ALGraph &G, int n) { G.vexnum = n; G.arcnum = 0 ; for (int i = 0 ; i < G.vexnum; i++) { G.vertices[i].data = 'A' + i; G.vertices[i].firstarc = NULL ; } } void AddUndirArc (ALGraph &G, int v1, int v2, int w) { ArcNode *p1 = (ArcNode *)malloc (sizeof (ArcNode)); p1->adjvex = v2; p1->weight = w; p1->nextarc = G.vertices[v1].firstarc; G.vertices[v1].firstarc = p1; ArcNode *p2 = (ArcNode *)malloc (sizeof (ArcNode)); p2->adjvex = v1; p2->weight = w; p2->nextarc = G.vertices[v2].firstarc; G.vertices[v2].firstarc = p2; G.arcnum++; } void AddDirArc (ALGraph &G, int v1, int v2, int w) { ArcNode *p = (ArcNode *)malloc (sizeof (ArcNode)); p->adjvex = v2; p->weight = w; p->nextarc = G.vertices[v1].firstarc; G.vertices[v1].firstarc = p; G.arcnum++; }
2. 图的遍历(DFS+BFS)
bool visited[MaxVertexNum];void DFS_MGraph (MGraph G, int v) { printf ("%c " , G.Vex[v]); visited[v] = true ; for (int w = 0 ; w < G.vexnum; w++) { if (G.Edge[v][w] != INF && G.Edge[v][w] != 0 && !visited[w]) { DFS_MGraph(G, w); } } } void DFS_ALGraph (ALGraph G, int v) { printf ("%c " , G.vertices[v].data); visited[v] = true ; ArcNode *p = G.vertices[v].firstarc; while (p != NULL ) { int w = p->adjvex; if (!visited[w]) { DFS_ALGraph(G, w); } p = p->nextarc; } } void BFS_MGraph (MGraph G, int v) { SqQueue Q; InitSqQueue(Q); printf ("%c " , G.Vex[v]); visited[v] = true ; EnQueue(Q, v); while (!QueueEmpty(Q)) { int u; DeQueue(Q, u); for (int w = 0 ; w < G.vexnum; w++) { if (G.Edge[u][w] != INF && G.Edge[u][w] != 0 && !visited[w]) { printf ("%c " , G.Vex[w]); visited[w] = true ; EnQueue(Q, w); } } } } void BFS_ALGraph (ALGraph G, int v) { SqQueue Q; InitSqQueue(Q); printf ("%c " , G.vertices[v].data); visited[v] = true ; EnQueue(Q, v); while (!QueueEmpty(Q)) { int u; DeQueue(Q, u); ArcNode *p = G.vertices[u].firstarc; while (p != NULL ) { int w = p->adjvex; if (!visited[w]) { printf ("%c " , G.vertices[w].data); visited[w] = true ; EnQueue(Q, w); } p = p->nextarc; } } } void TraverseGraph (ALGraph G) { for (int i = 0 ; i < G.vexnum; i++) { visited[i] = false ; } for (int i = 0 ; i < G.vexnum; i++) { if (!visited[i]) { DFS_ALGraph(G, i); } } }
3. 最小生成树(Prim算法+Kruskal算法)
3.1 Prim算法(邻接矩阵,从顶点出发)
void Prim (MGraph G, int v0) { int lowcost[MaxVertexNum]; int adjvex[MaxVertexNum]; int sum = 0 ; for (int i = 0 ; i < G.vexnum; i++) { lowcost[i] = G.Edge[v0][i]; adjvex[i] = v0; } lowcost[v0] = 0 ; for (int i = 1 ; i < G.vexnum; i++) { int min = INF; int k = -1 ; for (int j = 0 ; j < G.vexnum; j++) { if (lowcost[j] != 0 && lowcost[j] < min) { min = lowcost[j]; k = j; } } printf ("边(%c, %c) 权重:%d\n" , G.Vex[adjvex[k]], G.Vex[k], min); sum += min; lowcost[k] = 0 ; for (int j = 0 ; j < G.vexnum; j++) { if (lowcost[j] != 0 && G.Edge[k][j] < lowcost[j]) { lowcost[j] = G.Edge[k][j]; adjvex[j] = k; } } } printf ("最小生成树总权重:%d\n" , sum); }
3.2 Kruskal算法(按边选,需并查集)
typedef struct { int v1, v2; int weight; } Edge; int Find (int parent[], int u) { if (parent[u] != u) { parent[u] = Find(parent, parent[u]); } return parent[u]; } void Union (int parent[], int u, int v) { int rootU = Find(parent, u); int rootV = Find(parent, v); if (rootU != rootV) { parent[rootV] = rootU; } } void Kruskal (MGraph G) { Edge edges[MaxVertexNum * MaxVertexNum]; int edgeCnt = 0 ; int sum = 0 ; for (int i = 0 ; i < G.vexnum; i++) { for (int j = i + 1 ; j < G.vexnum; j++) { if (G.Edge[i][j] != INF && G.Edge[i][j] != 0 ) { edges[edgeCnt].v1 = i; edges[edgeCnt].v2 = j; edges[edgeCnt].weight = G.Edge[i][j]; edgeCnt++; } } } for (int i = 0 ; i < edgeCnt - 1 ; i++) { for (int j = 0 ; j < edgeCnt - i - 1 ; j++) { if (edges[j].weight > edges[j + 1 ].weight) { Edge temp = edges[j]; edges[j] = edges[j + 1 ]; edges[j + 1 ] = temp; } } } int parent[MaxVertexNum]; for (int i = 0 ; i < G.vexnum; i++) { parent[i] = i; } for (int i = 0 ; i < edgeCnt; i++) { int u = edges[i].v1; int v = edges[i].v2; int rootU = Find(parent, u); int rootV = Find(parent, v); if (rootU != rootV) { printf ("边(%c, %c) 权重:%d\n" , G.Vex[u], G.Vex[v], edges[i].weight); sum += edges[i].weight; Union(parent, u, v); } } printf ("最小生成树总权重:%d\n" , sum); }
4. 最短路径(Dijkstra算法)
void Dijkstra (MGraph G, int v0) { int dist[MaxVertexNum]; bool visited[MaxVertexNum]; int path[MaxVertexNum]; for (int i = 0 ; i < G.vexnum; i++) { dist[i] = G.Edge[v0][i]; visited[i] = false ; path[i] = (dist[i] != INF) ? v0 : -1 ; } dist[v0] = 0 ; visited[v0] = true ; for (int i = 1 ; i < G.vexnum; i++) { int min = INF; int u = -1 ; for (int j = 0 ; j < G.vexnum; j++) { if (!visited[j] && dist[j] < min) { min = dist[j]; u = j; } } if (u == -1 ) break ; visited[u] = true ; for (int w = 0 ; w < G.vexnum; w++) { if (!visited[w] && G.Edge[u][w] != INF && dist[u] + G.Edge[u][w] < dist[w]) { dist[w] = dist[u] + G.Edge[u][w]; path[w] = u; } } } for (int i = 0 ; i < G.vexnum; i++) { if (dist[i] == INF) { printf ("%c到%c:无路径\n" , G.Vex[v0], G.Vex[i]); } else { printf ("%c到%c:路径长度=%d,路径:" , G.Vex[v0], G.Vex[i], dist[i]); int temp[MaxVertexNum], cnt = 0 ; for (int j = i; j != -1 ; j = path[j]) { temp[cnt++] = j; } for (int j = cnt - 1 ; j >= 0 ; j--) { printf ("%c%s" , G.Vex[temp[j]], (j == 0 ) ? "\n" : "->" ); } } } }
5. 拓扑排序(AOV网,邻接表)
bool TopologicalSort (ALGraph G, int topo[]) { int inDegree[MaxVertexNum] = {0 }; SqQueue Q; InitSqQueue(Q); int count = 0 ; for (int i = 0 ; i < G.vexnum; i++) { ArcNode *p = G.vertices[i].firstarc; while (p != NULL ) { int w = p->adjvex; inDegree[w]++; p = p->nextarc; } } for (int i = 0 ; i < G.vexnum; i++) { if (inDegree[i] == 0 ) { EnQueue(Q, i); } } while (!QueueEmpty(Q)) { int u; DeQueue(Q, u); topo[count++] = u; ArcNode *p = G.vertices[u].firstarc; while (p != NULL ) { int w = p->adjvex; inDegree[w]--; if (inDegree[w] == 0 ) { EnQueue(Q, w); } p = p->nextarc; } } return count == G.vexnum; }
五、查找
1. 顺序查找(带哨兵)
typedef struct { ElemType *elem; int TableLen; } SSTable; int Search_Seq (SSTable ST, ElemType key) { ST.elem[0 ] = key; int i = ST.TableLen; while (ST.elem[i] != key) { i--; } return i; }
2. 折半查找(二分查找,有序顺序表)
int Binary_Search (SSTable L, ElemType key) { int low = 1 , high = L.TableLen; while (low <= high) { int mid = (low + high) / 2 ; if (L.elem[mid] == key) { return mid; } else if (L.elem[mid] > key) { high = mid - 1 ; } else { low = mid + 1 ; } } return -1 ; }
3. 散列表(哈希表)
3.1 线性探测法解决冲突
#define HashTableSize 13 #define NULL_KEY -32767 typedef struct { ElemType *elem; int count; } HashTable; bool InitHashTable (HashTable &HT) { HT.count = 0 ; HT.elem = (ElemType *)malloc (HashTableSize * sizeof (ElemType)); if (HT.elem == NULL ) return false ; for (int i = 0 ; i < HashTableSize; i++) { HT.elem[i] = NULL_KEY; } return true ; } int Hash (ElemType key) { return key % HashTableSize; } bool InsertHash_Linear (HashTable &HT, ElemType key) { if (HT.count >= HashTableSize) return false ; int addr = Hash(key); while (HT.elem[addr] != NULL_KEY) { addr = (addr + 1 ) % HashTableSize; } HT.elem[addr] = key; HT.count++; return true ; } int SearchHash_Linear (HashTable HT, ElemType key) { int addr = Hash(key); while (HT.elem[addr] != NULL_KEY && HT.elem[addr] != key) { addr = (addr + 1 ) % HashTableSize; } if (HT.elem[addr] == key) { return addr; } else { return -1 ; } }
3.2 拉链法解决冲突
typedef struct HashNode { ElemType key; struct HashNode *next ; } HashNode; typedef struct { HashNode *head[HashTableSize]; int count; } HashTable_Link; void InitHashTable_Link (HashTable_Link &HT) { HT.count = 0 ; for (int i = 0 ; i < HashTableSize; i++) { HT.head[i] = NULL ; } } bool InsertHash_Link (HashTable_Link &HT, ElemType key) { int addr = Hash(key); HashNode *p = (HashNode *)malloc (sizeof (HashNode)); if (p == NULL ) return false ; p->key = key; p->next = NULL ; if (HT.head[addr] == NULL ) { HT.head[addr] = p; } else { p->next = HT.head[addr]; HT.head[addr] = p; } HT.count++; return true ; } HashNode *SearchHash_Link (HashTable_Link HT, ElemType key) { int addr = Hash(key); HashNode *p = HT.head[addr]; while (p != NULL && p->key != key) { p = p->next; } return p; }
六、排序
1. 插入排序
1.1 直接插入排序
void InsertSort (ElemType A[], int n) { int i, j; for (i = 2 ; i <= n; i++) { if (A[i] < A[i - 1 ]) { A[0 ] = A[i]; for (j = i - 1 ; A[0 ] < A[j]; j--) { A[j + 1 ] = A[j]; } A[j + 1 ] = A[0 ]; } } }
1.2 希尔排序(增量序列d=5,3,1)
void ShellSort (ElemType A[], int n) { int i, j, d; for (d = 5 ; d >= 1 ; d--) { for (i = d + 1 ; i <= n; i++) { if (A[i] < A[i - d]) { A[0 ] = A[i]; for (j = i - d; j > 0 && A[0 ] < A[j]; j -= d) { A[j + d] = A[j]; } A[j + d] = A[0 ]; } } } }
2. 交换排序
2.1 冒泡排序
void BubbleSort (ElemType A[], int n) { for (int i = 0 ; i < n - 1 ; i++) { bool flag = false ; for (int j = n - 1 ; j > i; j--) { if (A[j - 1 ] > A[j]) { ElemType temp = A[j - 1 ]; A[j - 1 ] = A[j]; A[j] = temp; flag = true ; } } if (!flag) break ; } }
2.2 快速排序(递归)
int Partition (ElemType A[], int low, int high) { ElemType pivot = A[low]; while (low < high) { while (low < high && A[high] >= pivot) { high--; } A[low] = A[high]; while (low < high && A[low] <= pivot) { low++; } A[high] = A[low]; } A[low] = pivot; return low; } void QuickSort (ElemType A[], int low, int high) { if (low < high) { int pivotPos = Partition(A, low, high); QuickSort(A, low, pivotPos - 1 ); QuickSort(A, pivotPos + 1 , high); } }
3. 选择排序
3.1 简单选择排序
void SelectSort (ElemType A[], int n) { for (int i = 0 ; i < n - 1 ; i++) { int min = i; for (int j = i + 1 ; j < n; j++) { if (A[j] < A[min]) { min = j; } } if (min != i) { ElemType temp = A[i]; A[i] = A[min]; A[min] = temp; } } }
3.2 堆排序
void HeadAdjust (ElemType A[], int i, int n) { ElemType temp = A[i]; for (int j = 2 * i + 1 ; j < n; j = 2 * j + 1 ) { if (j + 1 < n && A[j] < A[j + 1 ]) { j++; } if (temp >= A[j]) { break ; } A[i] = A[j]; i = j; } A[i] = temp; } void BuildMaxHeap (ElemType A[], int n) { for (int i = n / 2 - 1 ; i >= 0 ; i--) { HeadAdjust(A, i, n); } } void HeapSort (ElemType A[], int n) { BuildMaxHeap(A, n); for (int i = n - 1 ; i > 0 ; i--) { ElemType temp = A[0 ]; A[0 ] = A[i]; A[i] = temp; HeadAdjust(A, 0 , i); } }
4. 归并排序(二路归并,递归)
void Merge (ElemType A[], int low, int mid, int high) { ElemType *B = (ElemType *)malloc ((high - low + 1 ) * sizeof (ElemType)); int i = low, j = mid + 1 , k = 0 ; while (i <= mid && j <= high) { if (A[i] <= A[j]) { B[k++] = A[i++]; } else { B[k++] = A[j++]; } } while (i <= mid) { B[k++] = A[i++]; } while (j <= high) { B[k++] = A[j++]; } for (k = 0 , i = low; i <= high; k++, i++) { A[i] = B[k]; } free (B); } void MergeSort (ElemType A[], int low, int high) { if (low < high) { int mid = (low + high) / 2 ; MergeSort(A, low, mid); MergeSort(A, mid + 1 , high); Merge(A, low, mid, high); } }
5. 基数排序(链式,按位排序)
typedef struct RadixNode { ElemType key; struct RadixNode *next ; } RadixNode, *RadixList; void RadixSort (RadixList &L, int maxBit) { RadixList queue [10 ], tail[10 ]; for (int i = 0 ; i < 10 ; i++) { queue [i] = (RadixNode *)malloc (sizeof (RadixNode)); queue [i]->next = NULL ; tail[i] = queue [i]; } RadixNode *p = L->next; for (int bit = 1 ; bit <= maxBit; bit++) { while (p != NULL ) { int digit = (p->key / (int )pow (10 , bit - 1 )) % 10 ; tail[digit]->next = p; tail[digit] = p; p = p->next; } p = L; for (int i = 0 ; i < 10 ; i++) { if (queue [i]->next != NULL ) { p->next = queue [i]->next; p = tail[i]; tail[i]->next = NULL ; } } p->next = NULL ; p = L->next; } for (int i = 0 ; i < 10 ; i++) { free (queue [i]); } }
七、串(String)
1. 串的定长顺序存储结构
#include <stdio.h> #include <string.h> #include <stdbool.h> #define MaxStrLen 255 typedef struct { char ch[MaxStrLen + 1 ]; int length; } SString;
2. 串的核心操作实现
bool StrCopy (SString &T, SString S) { if (S.length > MaxStrLen) return false ; for (int i = 1 ; i <= S.length; i++) { T.ch[i] = S.ch[i]; } T.length = S.length; return true ; } bool StrEmpty (SString S) { return S.length == 0 ; } int StrCompare (SString S, SString T) { for (int i = 1 ; i <= S.length && i <= T.length; i++) { if (S.ch[i] != T.ch[i]) { return S.ch[i] - T.ch[i]; } } return S.length - T.length; } int StrLength (SString S) { return S.length; } bool SubString (SString &Sub, SString S, int pos, int len) { if (pos < 1 || pos > S.length || len < 0 || len > S.length - pos + 1 ) { return false ; } for (int i = 1 ; i <= len; i++) { Sub.ch[i] = S.ch[pos + i - 1 ]; } Sub.length = len; return true ; } bool Concat (SString &T, SString S1, SString S2) { if (S1.length + S2.length > MaxStrLen) { return false ; } for (int i = 1 ; i <= S1.length; i++) { T.ch[i] = S1.ch[i]; } for (int i = 1 ; i <= S2.length; i++) { T.ch[S1.length + i] = S2.ch[i]; } T.length = S1.length + S2.length; return true ; } int Index (SString S, SString T) { int i = 1 ; int j = 1 ; while (i <= S.length && j <= T.length) { if (S.ch[i] == T.ch[j]) { i++; j++; } else { i = i - j + 2 ; j = 1 ; } } return j > T.length ? (i - T.length) : 0 ; }
八、矩阵压缩存储
1. 对称矩阵(下三角压缩存储)
#define MaxMatrixSize 100 typedef struct { int *data; int n; } SymmetricMatrix; bool InitSymmetricMatrix (SymmetricMatrix &M, int n) { if (n < 1 || n > MaxMatrixSize) return false ; M.n = n; int size = n * (n + 1 ) / 2 ; M.data = (int *)malloc (size * sizeof (int )); return M.data != NULL ; } int GetSymmetricValue (SymmetricMatrix M, int i, int j) { if (i < 1 || i > M.n || j < 1 || j > M.n) { printf ("矩阵下标越界\n" ); exit (1 ); } if (i < j) { int temp = i; i = j; j = temp; } int k = i * (i - 1 ) / 2 + j - 1 ; return M.data[k]; } bool SetSymmetricValue (SymmetricMatrix &M, int i, int j, int val) { if (i < 1 || i > M.n || j < 1 || j > M.n) return false ; if (i >= j) { int k = i * (i - 1 ) / 2 + j - 1 ; M.data[k] = val; } else { int k = j * (j - 1 ) / 2 + i - 1 ; M.data[k] = val; } return true ; }
2. 下三角矩阵(压缩存储)
typedef struct { int *data; int n; int c; } LowerTriMatrix; bool InitLowerTriMatrix (LowerTriMatrix &M, int n, int c) { if (n < 1 || n > MaxMatrixSize) return false ; M.n = n; M.c = c; int size = n * (n + 1 ) / 2 + 1 ; M.data = (int *)malloc (size * sizeof (int )); return M.data != NULL ; } int GetLowerTriValue (LowerTriMatrix M, int i, int j) { if (i < 1 || i > M.n || j < 1 || j > M.n) { printf ("矩阵下标越界\n" ); exit (1 ); } if (i >= j) { int k = i * (i - 1 ) / 2 + j - 1 ; return M.data[k]; } else { return M.c; } }
3. 稀疏矩阵(三元组顺序存储)
#define MaxTripleNum 1000 typedef struct { int i, j; int e; } Triple; typedef struct { Triple data[MaxTripleNum + 1 ]; int mu, nu, tu; } TSMatrix; bool TransposeTSMatrix (TSMatrix M, TSMatrix &T) { T.mu = M.nu; T.nu = M.mu; T.tu = M.tu; if (T.tu == 0 ) return true ; int col, p, q = 1 ; for (col = 1 ; col <= M.nu; col++) { for (p = 1 ; p <= M.tu; p++) { if (M.data[p].j == col) { T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].e = M.data[p].e; q++; } } } return true ; } bool FastTransposeTSMatrix (TSMatrix M, TSMatrix &T) { T.mu = M.nu; T.nu = M.mu; T.tu = M.tu; if (T.tu == 0 ) return true ; int *num = (int *)calloc (M.nu + 1 , sizeof (int )); int *cpot = (int *)malloc ((M.nu + 1 ) * sizeof (int )); if (num == NULL || cpot == NULL ) return false ; for (int p = 1 ; p <= M.tu; p++) { int col = M.data[p].j; num[col]++; } cpot[1 ] = 1 ; for (int col = 2 ; col <= M.nu; col++) { cpot[col] = cpot[col - 1 ] + num[col - 1 ]; } for (int p = 1 ; p <= M.tu; p++) { int col = M.data[p].j; int q = cpot[col]; T.data[q].i = M.data[p].j; T.data[q].j = M.data[p].i; T.data[q].e = M.data[p].e; cpot[col]++; } free (num); free (cpot); return true ; }
九、图的关键路径(AOE网)
1. AOE网的邻接表存储
typedef struct ArcNode { int adjvex; int weight; struct ArcNode *nextarc ; } ArcNode; typedef struct VNode { int inDegree; ArcNode *firstarc; } VNode; typedef struct { VNode vertices[MaxVertexNum + 1 ]; int vexnum, arcnum; } AOEGraph;
2. 关键路径算法实现
#include <stdlib.h> #include <limits.h> bool TopologicalSort_AOE (AOEGraph G, int topo[], int ve[]) { int queue [MaxVertexNum], front = 0 , rear = 0 ; int count = 0 ; for (int i = 1 ; i <= G.vexnum; i++) { ve[i] = 0 ; if (G.vertices[i].inDegree == 0 ) { queue [rear++] = i; } } while (front < rear) { int u = queue [front++]; topo[++count] = u; ArcNode *p = G.vertices[u].firstarc; while (p != NULL ) { int v = p->adjvex; G.vertices[v].inDegree--; if (ve[v] < ve[u] + p->weight) { ve[v] = ve[u] + p->weight; } if (G.vertices[v].inDegree == 0 ) { queue [rear++] = v; } p = p->nextarc; } } return count == G.vexnum; } void CriticalPath (AOEGraph G) { int *topo = (int *)malloc ((G.vexnum + 1 ) * sizeof (int )); int *ve = (int *)malloc ((G.vexnum + 1 ) * sizeof (int )); int *vl = (int *)malloc ((G.vexnum + 1 ) * sizeof (int )); if (!TopologicalSort_AOE(G, topo, ve)) { printf ("AOE网存在环,无关键路径\n" ); free (topo); free (ve); free (vl); return ; } for (int i = 1 ; i <= G.vexnum; i++) { vl[i] = ve[G.vexnum]; } for (int i = G.vexnum; i >= 1 ; i--) { int u = topo[i]; ArcNode *p = G.vertices[u].firstarc; while (p != NULL ) { int v = p->adjvex; if (vl[u] > vl[v] - p->weight) { vl[u] = vl[v] - p->weight; } p = p->nextarc; } } printf ("关键活动(u->v,持续时间,e,l,d):\n" ); for (int u = 1 ; u <= G.vexnum; u++) { ArcNode *p = G.vertices[u].firstarc; while (p != NULL ) { int v = p->adjvex; int weight = p->weight; int e = ve[u]; int l = vl[v] - weight; int d = l - e; if (d == 0 ) { printf ("关键活动:%d->%d,持续时间:%d,e=%d,l=%d,d=%d\n" , u, v, weight, e, l, d); } else { printf ("非关键活动:%d->%d,持续时间:%d,e=%d,l=%d,d=%d\n" , u, v, weight, e, l, d); } p = p->nextarc; } } free (topo); free (ve); free (vl); }
十、树与森林的转换
1. 树的孩子兄弟表示法
typedef struct CSNode { ElemType data; struct CSNode *firstChild ; struct CSNode *nextSibling ; } CSNode, *CSTree;
2. 树转换为二叉树
void TreeToBiTree (CSTree T, BiTree &BT) { if (T == NULL ) { BT = NULL ; return ; } BT = (BiTNode *)malloc (sizeof (BiTNode)); BT->data = T->data; BT->rchild = NULL ; TreeToBiTree(T->firstChild, BT->lchild); CSNode *sibling = T->firstChild != NULL ? T->firstChild->nextSibling : NULL ; BiTNode *p = BT->lchild; while (sibling != NULL ) { BiTNode *q = (BiTNode *)malloc (sizeof (BiTNode)); q->data = sibling->data; q->rchild = NULL ; TreeToBiTree(sibling->firstChild, q->lchild); p->rchild = q; p = q; sibling = sibling->nextSibling; } }
3. 森林转换为二叉树
void ForestToBiTree (CSTree forest[], int treeNum, BiTree &BT) { if (treeNum == 0 ) { BT = NULL ; return ; } TreeToBiTree(forest[0 ], BT); BiTNode *p = BT; for (int i = 1 ; i < treeNum; i++) { BiTree temp; TreeToBiTree(forest[i], temp); p->rchild = temp; p = temp; } }
十一、排序算法补充(基数排序)
#define Radix 10 typedef struct RadixNode { int key; struct RadixNode *next ; } RadixNode, *RadixList; void InitRadixList (RadixList &L) { L = (RadixNode *)malloc (sizeof (RadixNode)); L->next = NULL ; } void InsertRadixNode (RadixList &L, int key) { RadixNode *newNode = (RadixNode *)malloc (sizeof (RadixNode)); newNode->key = key; newNode->next = NULL ; RadixNode *p = L; while (p->next != NULL ) { p = p->next; } p->next = newNode; } int GetDigit (int key, int d) { for (int i = 1 ; i < d; i++) { key /= 10 ; } return key % 10 ; } void RadixSort (RadixList &L, int maxDigit) { RadixList bucket[Radix], bucketTail[Radix]; for (int i = 0 ; i < Radix; i++) { InitRadixList(bucket[i]); bucketTail[i] = bucket[i]; } RadixNode *p = L->next; for (int d = 1 ; d <= maxDigit; d++) { while (p != NULL ) { int digit = GetDigit(p->key, d); bucketTail[digit]->next = p; bucketTail[digit] = p; RadixNode *temp = p; p = p->next; temp->next = NULL ; } p = L; for (int i = 0 ; i < Radix; i++) { if (bucket[i]->next != NULL ) { p->next = bucket[i]->next; p = bucketTail[i]; bucket[i]->next = NULL ; bucketTail[i] = bucket[i]; } } p->next = NULL ; p = L->next; } for (int i = 0 ; i < Radix; i++) { free (bucket[i]); } }