目录
二叉树的结点定义
普通二叉树的链式存储结点定义
typedef struct BTNode {
char data; // 这里默认结点data域为char类型
struct BTNode *lchild; // 左儿子
struct BTNode *rchild; // 右儿子
}BTNode;
线索二叉树的结点定义
typedef struct TBTNode{
char data;
int ltag, rtag;
struct TBTNode *lchild;
struct TBTNode *rchild;
}TBTNode;
先序、中序、后序遍历(递归)
//先序遍历
void preorder(BTNode *p) {
if (p != nullptr) { // 一定要记得判空
printf("%c ", p->data);
preorder(p->lchild);
preorder(p->rchild);
}
}
//中序遍历
void inorder(BTNode *p) {
if (p != nullptr) {
inorder(p->lchild);
printf("%c ", p->data);
inorder(p->rchild);
}
}
//后序遍历
void postorder(BTNode *p) {
if (p != nullptr) {
postorder(p->lchild);
postorder(p->rchild);
printf("%c ", p->data);
}
}
层序遍历
/*
定义变量,判空,根入队
循环,出队,访左右
*/
void level(BTNode *bt) {
BTNode *que[maxSize];
BTNode *p = null;
int front = 0, rear = 0; // 定义一个循环队列
if (bt != null) {
rear = (rear+1) % maxSize;
que[rear] = bt; // 让根节点入队
while (front != rear) { // 只要队列不空,则进行循环
front = (front+1) % maxSize;
p = que[front]; // 队头元素出队
printf("%c\n", p->data); // 访问队头元素
if (p->lchild) { // 左子树存在,则左子树根节点入队
rear = (rear+1) % maxSize;
que[rear] = p->lchild;
}
if (p->rchild) { // 右子树存在,则右子树根节点入队
rear = (rear+1) % maxSize;
que[rear] = p->rchild;
}
}
}
先序遍历(非递归)
/*
定义变量,判空,根入栈
循环,出栈,访右左
*/
void preorderN(BTNode *bt) {
BTNode *Stack[maxSize];
BTNode *p;
int top = -1; // 定义人工栈
if (bt != null) {
Stack[++top] = bt; // 根节点入栈
while (top != -1) { // 判断不空
p = Stack[top--]; // 出栈 并完成一次访问
printf("%c\n", p->data);
if (p->rchild != null) // 记得,先序遍历一定是先右孩子,再左孩子
Stack[++top] = p->rchild;
if (p->lchild != null)
Stack[++top] = p->lchild;
}
}
}
中序遍历(非递归)
//思想:一直左坠,打印,访右
void inorderN(BTNode *bt) {
BTNode *Stack[maxSize];
BTNode *p = bt;
int top = -1;
if (bt != null) {
while (top != -1 || p != null) {
while (p != null) {
Stack[++top] = p;
p = p->lchild;
}
if (top != -1) {
p = Stack[top--];
printf("%c\n", p->data);
p = p->rchild;
}
}
}
}
后序遍历(非递归)
//思想:栈1访问,栈2存数据,最后一次打印栈2
void postorderN(BTNode *bt) {
BTNode *Stack1[maxSize]; int top1 = -1;
BTNode *Stack2[maxSize]; int top2 = -1; // 定义两个栈
BTNode *p;
if (bt != nullptr) {
Stack1[++top1] = bt;
while (top1 != -1) {
p = Stack1[top1--];
Stack2[++top2] = p; // 注意这里与先序的区别,放入栈2中即可
if (p->lchild)
Stack1[++top1] = p->lchild;
if (p->rchild)
Stack1[++top1] = p->rchild;
}
// 这时候循环结束,则会将逆后序遍历的结果都存放到了栈2中
// 所以对栈2进行输出即可得到后序遍历的结果
while (top2 != -1) {
p = Stack2[top2--];
printf("%c\n", p->data);
}
}
}
图的存储结构
邻接矩阵的结点定义
typedef struct {
int no; // 顶点编号
char info; // 顶点的其他信息,这里默认为char型。
}VertexType; // 顶点类型
typedef struct {
int edges[maxSize][maxSize]; // 有权图则将int改为float
int n, e; // 分别为定点数和边数
VertexType vex[maxSize]; // 存放节点信息
}MGraph; // 图的邻接矩阵类型
邻接表的结点定义
typedef struct ArcNode{
int adjvex; // 该边所指向的节点的位置
struct ArcNode *nextarc; // 指向下一条边的指针
int info; // 该边的相关信息(如权值)
}ArcNode;
typedef struct {
char data; // 定点信息
ArcNode *firstarc; // 指向第一条边的指针
}VNode;
typedef struct{
VNode adjlist[maxSize]; // 邻接表
int n, e; // 定点数和边数
}AGraph; // 图的邻接表类型
图的遍历方式DFS和BFS(修正)
void DFS(AGraph *G, int v){ //修正
ArcNode *p;
visit[v] = 1;
cout << v << endl;
p = G->adjlist[v].firstarc; // 让p指向顶点v的第一条边
while (p != null) {
if (visit[p->adjvex] == 0) DFS(G, p->adjvex);
p = p->nextarc;
}
}
void BFS(AGraph *G, int v){
ArcNode *p;
int que[maxSize]
int front = 0, rear = 0; // 定义一个队列
int j;
visit[v] = 1;
cout << v << endl;
rear = (rear+1)%maxSize; // 入队
que[rear] = v;
while (front != rear){
front = (front+1)%maxSize; // 顶点出队
j = que[front];
p = G->adjlist[j].firstarc; // p指向出队顶点j的第一条边
while (p != null) { // 将p的所有邻接点未被访问的入队
if (visit[p->adjvex] == 0) {
rear = (rear+1)%maxSize;
que[rear] = p->adjvex;
}
p = p->nextarc;
}
}
}
排序算法
折半插入排序
void BInsertSort(int A[],int n) {
int i,j,temp;
int low,mid,high;
for(i=1; i<n; i++) {
low=0;
high=i-1;
temp=A[i];
while(low <= high) { // 下面的折半是为了在i元素的前面查找到合适的插入位置
mid=(low+high)/2;
if(A[mid]>temp) high=mid-1;
else low=mid+1;
}
for(j=i-1;j>high;j--) A[j+1]=A[j]; //注意这里的下界,需要考虑两种情况
A[j+1]=temp;
}
}
起泡排序
void BubbleSort(int arr[], int n) {
int temp;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n-i-1; ++j) {
if (arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
快速排序
void _quickSort(int nums[], int l, int r) {
if (l >= r) return;
int pivot = nums[l];
int low = l+1, high = r;
while(low <= high) {
if(nums[low] > pivot && nums[high] < pivot)
swap(nums[low++], nums[high--]);
if(low <= high && nums[low] <= pivot) ++low; // 一定要带等号
if(low <= high && nums[high] >= pivot) --high;
}
swap(nums[l], nums[high]);
int p = high;
_quickSort(nums, l, p-1);
_quickSort(nums, p+1, r);
}
归并算法
void _merge(int A[], int l, int mid, int r) {
int temp[r-l+1];
int i = l, j = mid + 1;
int m = mid, n = r;
int k = 0;
while (i <= m && j <= n) {
if (A[i] <= A[j]) temp[k++] = A[i++];
else temp[k++] = A[j++];
}
while (i <= m) temp[k++] = A[i++];
while (j <= n) temp[k++] = A[j++];
for (i = 0; i < k; i++) A[l+i] = temp[i];
}
void _mergeSort(A arr[], int l, int r) {
if (l >= r) return;
int mid = l + (r-l)/2;
_mergeSort(arr, l, mid);
_mergeSort(arr, mid+1, r);
_merge(arr, l, mid, r);
}
其他细节总结
合并两个顺序表
bool merge(SeqList A,SeqList B,SeqList C){
if(A.length + B.length > C.length) 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;
}
判断链表是否有环(快慢指针的思想)
typedef struct ListNode {
int val;
struct ListNode *next;
};
bool hasCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while(fast && fast->next)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
return true;
}
return false;
}
逆转数组
void Reverse(int A[],int l,int r){
int i,temp;
for(i=0; i<(r-l+1)/2;i++)
swap(A[l+i],A[r-i]);
}
void Converse(int A,int n,int p){
Reverse(A,0,p-1);
Reverse(A,p,n-1);
Reverse(A,0,n-1);
}
申请数组等
int*q=(int*)malloc(sizeof(int)*(n+1));
//对p的访问是,p[2]或*(p+2)
//释放p:free(p); 使用完记得释放
char *pStr =(char*)malloc(sizeof(char)*n);
//全局变量用静态
static int sum=0;
//memset是按字节赋值的,对int数组只能赋值0和-1
memset(a,0,sizeof(a));
memset(a,-1,sizeof(a));
二分查找
void BSearch(int A[],int n,int x){
int low=0,high=n-1,mid;
while(low<=high){
mid=(low+high)/2;
if(A[mid]==x) break;
else if(A[mid]<x) low=mid+1;
else high=mid-1;
}
if(low>high){
for(int j=n-1;j>high;j--) A[j+1]=A[j];
A[j+1]=x;
}
}