目录
序:建大堆(如果建小堆的话,小堆不一定有序,只是堆顶最小,那下一个最小的数呢?如何依次选最小的数据?就算是选出来了之后,结点之间的关系就全乱了,无法继续利用优势,只能重新建堆O(N),选出次小的数据,效率太低了)建大堆直接交换堆顶和最后一个,进行向下调整即可
这里的建堆,是直接用数组进行建堆,可以用向上调整算法进行建堆,也可以利用向下调整建堆,有什么区别?我们先来看代码的实现:
- //建堆——a,利用向上调整建堆——O(N*logN)
- //直接插入
- /*for (int i = 1; i < n; i++)
- {
- AdjustUp(a, i);
- }*/
- //建完堆之后无序,我们排个序
-
-
- //建堆——向下调整建堆(从最后一个节点的父亲开始,开始向下调整,直到根)——O(N)
- for (int i = (n-1-1)/2; i>=0; i--)
- {
- AdjustDown(a, n, i);
- }
两种的时间复杂度不一样:向上调整建堆的时间复杂度是O(N*logN);向下调整建堆的时间复杂度是O(N)。所以我们选用的是向下调整算法进行建堆,关于向下调整算法时间复杂度的推导过程:
因此:建堆的时间复杂度为O(N)。
了解完后我们下面来实现排序
#define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> //向下调整 void swap(int* p1, int* p2) { int tmp = *p1; *p1 = *p2; *p2 = tmp; } void adjustdown(int* a, int n, int parent) { //默认左孩子为最小值 int minchild = parent * 2 + 1; while (minchild < n) { if (minchild + 1 < n && a[minchild] > a[minchild + 1]) { minchild++; } if (a[minchild] < a[parent]) { swap(&a[minchild], &a[parent]); parent = minchild; minchild = parent * 2 + 1; } else { break; } } } //建堆 void HeapSort(int* a, int n) { //建堆——a,利用向上调整建堆 //直接插入 /*for (int i = 1; i < n; i++) { AdjustUp(a, i); }*/ //建完堆之后无序,我们排个序 //建堆——向下调整建堆(从最后一个节点的父亲开始,开始向下调整,直到根) int i = 0; for (i = (n - 1 - 1) / 2; i >= 0; i--) { adjustdown(a, n, i); } //选数 i = 1; while (i < n) { swap(&a[0], &a[n - i]); adjustdown(a, n - i, 0); i++; } } int main() { int a[] = { 15,1,19,25,8,34,65,4,27,7 }; HeapSort(a, sizeof(a) / sizeof(int)); for (int i = 0; i < sizeof(a) / sizeof(int); i++) { printf("%d ", a[i]); } printf("\n"); return 0; }这里建的是小堆所以是降序
在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。为了降低学习成本,此处手动快速创建一棵简单的二叉树,这里以简单的实现为主。后续在来讨论其创建方式:
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int BTDataType; typedef struct BinaryTreeNode { BTDataType data; struct BinaryTreeNode* left; struct BinaryTreeNode* right; }BTNode; BTNode* CreatTree() { BTNode* n1 = (BTNode*)malloc(sizeof(BTNode)); assert(n1); BTNode* n2 = (BTNode*)malloc(sizeof(BTNode)); assert(n2); BTNode* n3 = (BTNode*)malloc(sizeof(BTNode)); assert(n3); BTNode* n4 = (BTNode*)malloc(sizeof(BTNode)); assert(n4); BTNode* n5 = (BTNode*)malloc(sizeof(BTNode)); assert(n5); BTNode* n6 = (BTNode*)malloc(sizeof(BTNode)); assert(n6); n1->data = 1; n2->data = 2; n3->data = 3; n4->data = 4; n5->data = 5; n6->data = 6; n1->left = n2; n1->right = n4; n2->left = n3; n2->right = NULL; n3->left = NULL; n3->right = NULL; n4->left = n5; n4->right = n6; n5->left = NULL; n5->right = NULL; n6->left = NULL; n6->right = NULL; return n1; } int main() { BTNode* root = CreatTree(); return 0; }这就大概搭建起了二叉树的框架,下面,来说一说其操作:
//前序 void PreOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } printf("%d ", root->data); PreOrder(root->left); PreOrder(root->right); } //中序 void InOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } InOrder(root->left); printf("%d ", root->data); InOrder(root->right); } //后续 void PostOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } PostOrder(root->left); PostOrder(root->right); printf("%d ", root->data); }
我们不难发现,二叉树的遍历操作通过递归实现非常地简单,实现并不难,但是你真的理解了吗函数怎么执行的(我们这里以前序遍历为例)
完整代码
- #define _CRT_SECURE_NO_WARNINGS 1
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- typedef int BTDataType;
-
- typedef struct BinaryTreeNode
- {
- BTDataType data;
- struct BinaryTreeNode* left;
- struct BinaryTreeNode* right;
- }BTNode;
-
-
- BTNode* CreatTree()
- {
- BTNode* n1 = (BTNode*)malloc(sizeof(BTNode));
- assert(n1);
- BTNode* n2 = (BTNode*)malloc(sizeof(BTNode));
- assert(n2);
- BTNode* n3 = (BTNode*)malloc(sizeof(BTNode));
- assert(n3);
- BTNode* n4 = (BTNode*)malloc(sizeof(BTNode));
- assert(n4);
- BTNode* n5 = (BTNode*)malloc(sizeof(BTNode));
- assert(n5);
- BTNode* n6 = (BTNode*)malloc(sizeof(BTNode));
- assert(n6);
-
- n1->data = 1;
- n2->data = 2;
- n3->data = 3;
- n4->data = 4;
- n5->data = 5;
- n6->data = 6;
-
- n1->left = n2;
- n1->right = n4;
- n2->left = n3;
- n2->right = NULL;
- n3->left = NULL;
- n3->right = NULL;
- n4->left = n5;
- n4->right = n6;
- n5->left = NULL;
- n5->right = NULL;
- n6->left = NULL;
- n6->right = NULL;
-
- return n1;
- }
- //前序
- void PreOrder(BTNode* root)
- {
- if (root == NULL)
- {
- printf("NULL ");
- return;
- }
- printf("%d ", root->data);
- PreOrder(root->left);
- PreOrder(root->right);
- }
- //中序
- void InOrder(BTNode* root)
- {
- if (root == NULL)
- {
- printf("NULL ");
- return;
- }
- InOrder(root->left);
- printf("%d ", root->data);
- InOrder(root->right);
- }
- //后续
- void PostOrder(BTNode* root)
- {
- if (root == NULL)
- {
- printf("NULL ");
- return;
- }
- PostOrder(root->left);
-
- PostOrder(root->right);
- printf("%d ", root->data);
- }
- int main()
- {
- BTNode* root = CreatTree();
- PreOrder(root);
- printf("\n");
- InOrder(root);
- printf("\n");
- PostOrder(root);
- return 0;
- }
结点个数
- //结点个数
- int TreeSize(BTNode* root)
- {
- if (root == NULL)
- return 0;
- return TreeSize(root->left) +
- TreeSize(root->right) + 1;
- }
叶结点个数
- //叶子结点个数
- int TreeLeafSize(BTNode* root)
- {
- if (root == NULL)
- return 0;
- if (root->left == NULL && root->right == NULL)
- return 1;
- return TreeLeafSize(root->left) + TreeLeafSize(root->right);
- }
高度
//高度 int TreeHeighrt(BTNode* root) { if (root == NULL) { return 0; } int left = TreeHeighrt(root->left); int right = TreeHeighrt(root->right); return left > right ? left + 1 : right + 1; }
求第K层结点个数
//k层的结点数 int TreeLeveL(BTNode* root, int k) { assert(k > 0); if (root == NULL) { return 0; } if (k == 1) { return 1; } return TreeLeveL(root->left, k - 1) + TreeLeveL(root->right, k - 1); }
返回x所在的结点
//返回X所在的结点 BTNode* TreeFind(BTNode* root, BTDataType x) { if (root == NULL) return NULL; if (root->data == x) return root; //先去左树找 BTNode* left = TreeFind(root->left, x); if (left != NULL) return left; //左树找不到,在去右树找 BTNode* right = TreeFind(root->right, x); if (right != NULL) return right; return NULL; }
完整代码
#define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <assert.h> #include <stdlib.h> typedef int BTDataType; typedef struct BinaryTreeNode { BTDataType data; struct BinaryTreeNode* left; struct BinaryTreeNode* right; }BTNode; BTNode* CreatTree() { BTNode* n1 = (BTNode*)malloc(sizeof(BTNode)); assert(n1); BTNode* n2 = (BTNode*)malloc(sizeof(BTNode)); assert(n2); BTNode* n3 = (BTNode*)malloc(sizeof(BTNode)); assert(n3); BTNode* n4 = (BTNode*)malloc(sizeof(BTNode)); assert(n4); BTNode* n5 = (BTNode*)malloc(sizeof(BTNode)); assert(n5); BTNode* n6 = (BTNode*)malloc(sizeof(BTNode)); assert(n6); n1->data = 1; n2->data = 2; n3->data = 3; n4->data = 4; n5->data = 5; n6->data = 6; n1->left = n2; n1->right = n4; n2->left = n3; n2->right = NULL; n3->left = NULL; n3->right = NULL; n4->left = n5; n4->right = n6; n5->left = NULL; n5->right = NULL; n6->left = NULL; n6->right = NULL; return n1; } //前序 void PreOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } printf("%d ", root->data); PreOrder(root->left); PreOrder(root->right); } //中序 void InOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } InOrder(root->left); printf("%d ", root->data); InOrder(root->right); } //后续 void PostOrder(BTNode* root) { if (root == NULL) { printf("NULL "); return; } PostOrder(root->left); PostOrder(root->right); printf("%d ", root->data); } //结点个数 int TreeSize(BTNode* root) { if (root == NULL) return 0; return TreeSize(root->left) + TreeSize(root->right) + 1; } //叶子结点个数 int TreeLeafSize(BTNode* root) { if (root == NULL) return 0; if (root->left == NULL && root->right == NULL) return 1; return TreeLeafSize(root->left) + TreeLeafSize(root->right); } //高度 int TreeHeighrt(BTNode* root) { if (root == NULL) { return 0; } int left = TreeHeighrt(root->left); int right = TreeHeighrt(root->right); return left > right ? left + 1 : right + 1; } //k层的结点数 int TreeLeveL(BTNode* root, int k) { assert(k > 0); if (root == NULL) { return 0; } if (k == 1) { return 1; } return TreeLeveL(root->left, k - 1) + TreeLeveL(root->right, k - 1); } //返回X所在的结点 BTNode* TreeFind(BTNode* root, BTDataType x) { if (root == NULL) return NULL; if (root->data == x) return root; //先去左树找 BTNode* left = TreeFind(root->left, x); if (left != NULL) return left; //左树找不到,在去右树找 BTNode* right = TreeFind(root->right, x); if (right != NULL) return right; return NULL; } int main() { BTNode* root = CreatTree(); PreOrder(root); printf("\n"); InOrder(root); printf("\n"); PostOrder(root); printf("\n"); printf("Size:%d\n", TreeSize(root)); printf("LeafSize:%d\n", TreeLeafSize(root)); printf("LeafHeighrt:%d\n", TreeHeighrt(root)); printf("TreeLeveL:%d\n", TreeLeveL(root,3)); printf("Tree Find:%p\n", TreeFind(root, 8)); return 0; }