1
0
mirror of https://github.com/Didnelpsun/CS408.git synced 2026-02-08 05:14:48 +08:00

更新排序

This commit is contained in:
Didnelpsun
2021-09-30 23:39:01 +08:00
parent 7b91890693
commit ae1d32460e
16 changed files with 322 additions and 235 deletions

View File

@@ -1,43 +1,43 @@
#include "head.h"
// 邻接矩阵图
// 邻接矩阵图
typedef struct {
// 顶点表
// 顶点表
element_type* vex;
// 边表
// 边表
weight_type *edge;
// 定点数
// 定点数
int vex_length;
// 边数
// 边数
int edge_length;
} AdjacentArrayGraph;
// 邻接表图
// 边表结点
// 邻接表图
// 边表结点
typedef struct EdgeNode{
// 该弧指向顶点的位置
// 该弧指向顶点的位置
int vex;
// 指向下条弧的指针
// 指向下条弧的指针
struct EdgeNode *next;
// 边权值
// 边权值
weight_type weigh;
} EdgeNode;
// 顶点表结点
// 顶点表结点
typedef struct VexNode{
// 顶点信息
// 顶点信息
element_type data;
..
// 指向第一条依赖该顶点的弧的指针
EdgeNode* frist;
} VexNode, *AdjacentList;
// 邻接表
// 邻接表
typedef struct {
// 邻接表数据
// 邻接表数据
AdjacentList data;
// 顶点数
// 顶点数
int vex_length;
// 边数
// 边数
int edge_length;
} AdjacentListGraph;

View File

@@ -1,3 +1,5 @@
//#pragma once
// 初始化最大长度
#define MAXSIZE 5
// 定义默认值
@@ -11,7 +13,5 @@ typedef char element_type;
// 权值类型
typedef int weight_type;
// 比较元素方法
int CompareElem(element_type elem1, element_type elem2){
return 0;
}
typedef int elem_type;

View File

@@ -1,24 +1,24 @@
#include "head.h"
// 链队结点
// 链队结点
typedef struct LinkQueueNode {
// 数据
// 数据
element_type data;
// 指针
// 指针
struct LinkQueueNode *next;
} LinkQueueNode;
// 链队
// 链队
typedef struct {
// 队头指针和队尾指针
// 队头指针和队尾指针
LinkQueueNode *front, *rear;
} LinkQueue;
// 初始化
// 初始化
bool InitLinkQueue(LinkQueue &queue){
// 建立头节点
// 建立头节点
queue.front = queue.rear = (LinkQueueNode*) malloc(sizeof(LinkQueueNode));
// 初始为空
// 初始为空
queue.front->next = nullptr;
queue.front->data = DEFAULTELEM;
return true;
@@ -27,40 +27,40 @@ bool InitLinkQueue(LinkQueue &queue){
LinkQueue InitLinkQueue(){
auto* queue = (LinkQueue*) malloc(sizeof(LinkQueue));
queue->front = queue->rear = (LinkQueueNode*) malloc(sizeof(LinkQueueNode));
// 初始为空
// 初始为空
queue->front->next = nullptr;
queue->front->data = DEFAULTELEM;
return (LinkQueue &) queue;
}
// 判空
// 判空
bool EmptyLinkQueue(LinkQueue queue){
return queue.front==queue.rear;
}
// 入队
// 入队
bool EnterLinkQueue(LinkQueue &queue, element_type elem){
// 创建新结点
// 创建新结点
auto *node = (LinkQueueNode *) malloc(sizeof(LinkQueueNode));
node->data = elem;
node->next = nullptr;
// 把最后一个元素的next连接到node
// 把最后一个元素的next连接到node
queue.rear->next = node;
// 移动尾指针
// 移动尾指针
queue.rear = node;
return true;
}
// 出队
// 出队
element_type DepartLinkQueue(LinkQueue &queue){
if(EmptyLinkQueue(queue)){
printf("DepartLinkQueue:The queue is empty!");
return false;
}
// 获取对首元素下一个元素的数据
// 获取对首元素下一个元素的数据
element_type elem = queue.front->next->data;
// 后移移位
// 后移移位
queue.front->next=queue.front->next->next;
// 若队列空
// 若队列空
return true;
}

View File

@@ -1,14 +1,14 @@
#include "head.h"
// 链栈
// 链栈
typedef struct LinkStackNode{
// 数据
// 数据
element_type data;
// 指针
// 指针
LinkStackNode *next;
} *LinkStack;
// 初始化
// 初始化
LinkStack InitLinkStack(){
auto stack = (LinkStack) malloc(sizeof(LinkStack));
stack->data = DEFAULTELEM;
@@ -22,7 +22,7 @@ bool InitLinkStack(LinkStack &stack){
return true;
}
// 判空
// 判空
bool EmptyLinkStack(LinkStack stack){
return stack->data == DEFAULTELEM;
};

View File

@@ -1,10 +1,10 @@
#include "head.h"
// 块链串结点
// ¿éÁ´´®½áµã
typedef struct LinkStringNode {
// 数据
// Êý¾Ý
char *data;
// 指针
// Ö¸Õë
LinkStringNode *next;
} LinkStringNode, *LinkString;

View File

@@ -2,13 +2,18 @@
#include <stack>
#include <queue>
// 二叉树结点
// 比较元素方法
int CompareElem(element_type elem1, element_type elem2){
return 0;
}
// 二叉树结点
typedef struct BinaryTreeNode {
element_type data;
BinaryTreeNode *left_child, *right_child;
} BinaryTreeNode, *BinaryTree;
// 前序遍历
// 前序遍历
bool PreOrderBinaryTree(BinaryTree &tree, bool( *function)(BinaryTree &)) {
if (tree != nullptr) {
if (!function(tree))
@@ -19,7 +24,7 @@ bool PreOrderBinaryTree(BinaryTree &tree, bool( *function)(BinaryTree &)) {
return true;
}
// 中序遍历
// 中序遍历
bool InOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
if (tree != nullptr) {
PreOrderBinaryTree(tree->left_child, function);
@@ -30,7 +35,7 @@ bool InOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
return true;
}
// 后序遍历
// 后序遍历
bool PostOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
if (tree != nullptr) {
PreOrderBinaryTree(tree->left_child, function);
@@ -41,93 +46,93 @@ bool PostOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
return true;
}
// 非递归先序遍历
// 非递归先序遍历
bool PreOrderNonRecursiveBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
// 初始化栈栈元素为tree指针
// 初始化栈栈元素为tree指针
std::stack<BinaryTree> stack;
// 赋值一个新树
// 赋值一个新树
BinaryTree new_tree = tree;
// 如果栈不空或new_tree不空时循环
// 如果栈不空或new_tree不空时循环
while (new_tree || !stack.empty()) {
// 一直向左
// 一直向左
if (new_tree) {
// 访问当前结点
// 访问当前结点
if (!function(new_tree)) {
printf("PreOrderNonRecursive:访问结点失败!");
printf("PreOrderNonRecursive:访问结点失败!");
return false;
}
// 当前结点入栈
// 当前结点入栈
stack.push(new_tree);
// 左孩子不空则一直向左
// 左孩子不空则一直向左
new_tree = new_tree->left_child;
}
// 出栈,并转向右子树
// 出栈,并转向右子树
else {
// 返回栈顶的元素,但不删除该元素
// 返回栈顶的元素,但不删除该元素
new_tree = stack.top();
// 删除栈顶元素但不返回其值
// 删除栈顶元素但不返回其值
stack.pop();
// 向右
// 向右
new_tree = new_tree->right_child;
// 返回while
// 返回while
}
}
return true;
}
// 非递归中序遍历
// 非递归中序遍历
bool InOrderNonRecursiveBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
// 初始化栈栈元素为tree指针
// 初始化栈栈元素为tree指针
std::stack<BinaryTree> stack;
// 赋值一个新树
// 赋值一个新树
BinaryTree new_tree = tree;
// 如果栈不空或new_tree不空时循环
// 如果栈不空或new_tree不空时循环
while (new_tree || !stack.empty()) {
// 一直向左
// 一直向左
if (new_tree) {
// 当前结点入栈
// 当前结点入栈
stack.push(new_tree);
// 左孩子不空则一直向左
// 左孩子不空则一直向左
new_tree = new_tree->left_child;
}
// 出栈,并转向右子树
// 出栈,并转向右子树
else {
// 返回栈顶的元素,但不删除该元素
// 返回栈顶的元素,但不删除该元素
new_tree = stack.top();
// 删除栈顶元素但不返回其值
// 删除栈顶元素但不返回其值
stack.pop();
// 访问出栈结点
// 访问出栈结点
if (!function(new_tree)) {
printf("InOrderNonRecursive:访问结点失败!");
printf("InOrderNonRecursive:访问结点失败!");
return false;
}
// 向右
// 向右
new_tree = new_tree->right_child;
// 返回while
// 返回while
}
}
return true;
}
// 层序遍历
// 层序遍历
bool LevelOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
// 初始化辅助队列
// 初始化辅助队列
std::queue<BinaryTree> queue;
// 初始化树结点
// 初始化树结点
BinaryTree new_tree = tree;
// 根结点入队
// 根结点入队
queue.push(new_tree);
// 若队列非空则循环
// 若队列非空则循环
while (!queue.empty()) {
// 队头结点出队
// 队头结点出队
new_tree = queue.front();
queue.pop();
// 访问出队结点
// 访问出队结点
if (!function(new_tree)) {
printf("LevelOrder:访问结点失败!");
printf("LevelOrder:访问结点失败!");
return false;
}
// 如果左子树不空则其根结点入队
// 如果左子树不空则其根结点入队
if (new_tree->left_child != nullptr) {
queue.push(new_tree);
}
@@ -138,12 +143,12 @@ bool LevelOrderBinaryTree(BinaryTree &tree, bool(*function)(BinaryTree &)) {
return true;
}
// 二叉排序树查找
// 二叉排序树查找
BinaryTreeNode *SearchBinarySortTree(BinaryTree tree, element_type elem) {
BinaryTree node = tree;
// 若树空或等于根结点值就结束循环
// 若树空或等于根结点值就结束循环
while (node != nullptr && elem != node->data) {
// 若小于则左子树查找
// 若小于则左子树查找
if (CompareElem(elem, node->data) < 0)
node = node->left_child;
else
@@ -152,33 +157,33 @@ BinaryTreeNode *SearchBinarySortTree(BinaryTree tree, element_type elem) {
return node;
}
// 二叉排序树插入
// 二叉排序树插入
bool InsertBinarySortTree(BinaryTree &tree, element_type elem) {
if (elem == NULL){
printf("InsertBinarySortTree:插入数据不应为空!\n");
printf("InsertBinarySortTree:插入数据不应为空!\n");
return false;
}
// 若原树为空,则将新插入的记录作为根结点
// 若原树为空,则将新插入的记录作为根结点
if (tree == nullptr) {
tree = (BinaryTree) malloc(sizeof(BinaryTreeNode));
tree->data = elem;
tree->left_child = tree->right_child = nullptr;
return true;
}
// 若存在相同关键字的结点则插入失败
// 若存在相同关键字的结点则插入失败
else if (CompareElem(elem, tree->data) == 0)
return false;
// 若小于则插入到左子树
// 若小于则插入到左子树
else if (CompareElem(elem, tree->data) < 0)
return InsertBinarySortTree(tree->left_child, elem);
// 否则插入到右子树
// 否则插入到右子树
else
return InsertBinarySortTree(tree->right_child, elem);
}
// 构造二叉排序树
// 构造二叉排序树
bool CreateBinarySortTree(BinaryTree &tree, element_type* elem, int start, int length){
// 将树初始化
// 将树初始化
tree = nullptr;
int i = 0;
while(i<length){
@@ -189,5 +194,5 @@ bool CreateBinarySortTree(BinaryTree &tree, element_type* elem, int start, int l
return true;
}
// 删除二叉排序树
bool DeleteBinarySortTree()
// 删除二叉排序树
bool DeleteBinarySortTree();

View File

@@ -1,30 +1,28 @@
#include "head.h"
typedef int elem_type
// 线性表
// 线性表
typedef struct {
elem_type *elem;
elem_type *data;
int length;
} LinearTable;
// 顺序查找
// 顺序查找
int SequenceSearch(LinearTable table, elem_type key) {
for (int i = 0; i < table.length; i++) {
if (table.elem[i] == key)
if (table.data[i] == key)
return i;
}
return -1;
}
// 折半查找
// 折半查找
int BinarySearch(LinearTable table, elem_type key) {
int low = 0, high = table.length - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (table.elem[mid] == key)
if (table.data[mid] == key)
return mid;
else if (table.elem[mid] > key)
else if (table.data[mid] > key)
high = mid - 1;
else
low = mid + 1;

View File

@@ -1,16 +1,16 @@
#include "head.h"
// 顺序队列
// 顺序队列
typedef struct {
// 数据
// 数据
element_type *data;
// 队头、队尾
// 队头、队尾
int front, rear;
// 队列最大容量
// 队列最大容量
int max_size;
} SequenceQueue;
// 初始化
// 初始化
bool InitSequenceQueue(SequenceQueue &queue) {
queue.data = (element_type *) malloc(sizeof(element_type) * MAXSIZE);
queue.front = 0;
@@ -45,37 +45,37 @@ SequenceQueue InitSequenceQueue(int max_size) {
return (SequenceQueue &) queue;
}
// 判空
// 判空
bool EmptySequenceQueue(SequenceQueue queue) {
return queue.front == queue.rear;
}
// 判满(存在假溢出)
// 判满(存在假溢出)
bool FullSequenceQueue(SequenceQueue queue) {
return queue.rear == queue.max_size;
}
// 判循环队列满
// 判循环队列满
bool FullCircularSequenceQueue(SequenceQueue queue) {
return (queue.rear + 1) % queue.max_size == queue.front;
}
// 进队
// 进队
bool EnterSequenceQueue(SequenceQueue &queue, element_type elem) {
// 判断队满
// 判断队满
if (FullSequenceQueue(queue)) {
printf("EnterSequenceQueue:队满无法进队!\n");
printf("EnterSequenceQueue:队满无法进队!\n");
return false;
}
queue.data[queue.rear++] = elem;
return true;
}
// 进循环队
// 进循环队
bool EnterCircularSequenceQueue(SequenceQueue &queue, element_type elem) {
// 判循环队满
// 判循环队满
if (FullCircularSequenceQueue(queue)) {
printf("EnterCircularSequenceQueue:队满无法进队!\n");
printf("EnterCircularSequenceQueue:队满无法进队!\n");
return false;
}
queue.data[queue.rear] = elem;
@@ -83,21 +83,21 @@ bool EnterCircularSequenceQueue(SequenceQueue &queue, element_type elem) {
return true;
}
// 出队
// 出队
element_type DepartSequenceQueue(SequenceQueue &queue) {
// 判断队空
// 判断队空
if (EmptySequenceQueue(queue)) {
printf("DepartSequenceQueue:队空无法出队!\n");
printf("DepartSequenceQueue:队空无法出队!\n");
return DEFAULTELEM;
}
return queue.data[queue.front++];
}
// 出循环队
// 出循环队
element_type DepartCircularDepartSequence(SequenceQueue &queue) {
// 判断队空
// 判断队空
if (EmptySequenceQueue(queue)) {
printf("DepartCircularDepartSequence:队空无法出队!\n");
printf("DepartCircularDepartSequence:队空无法出队!\n");
return DEFAULTELEM;
}
element_type elem = queue.data[queue.front];
@@ -105,16 +105,16 @@ element_type DepartCircularDepartSequence(SequenceQueue &queue) {
return elem;
}
// 获取队长
// 获取队长
int LengthSequenceQueue(SequenceQueue queue) {
return (queue.rear - queue.front + queue.max_size) % queue.max_size;
}
// 读队头
// 读队头
element_type HeadSequenceQueue(SequenceQueue &queue) {
// 判断队空
// 判断队空
if (EmptySequenceQueue(queue)) {
printf("HeadSequenceQueue:队空无法读队头!\n");
printf("HeadSequenceQueue:队空无法读队头!\n");
return DEFAULTELEM;
}
return queue.data[queue.front];

View File

@@ -1,12 +1,12 @@
#include "head.h"
// 顺序串
// 顺序串
typedef struct {
// 数据
// 数据
char *data;
// 长度
// 长度
int length;
// 最大容量
// 最大容量
int max_size;
} SequenceString;
@@ -40,16 +40,16 @@ SequenceString InitSequenceString(int max_size) {
return (SequenceString &) string;
}
// 简单字符串匹配
// 简单字符串匹配
int LocateSimple(SequenceString string, SequenceString pattern) {
int i = 0, j = 0;
while (i < string.length && j < pattern.length) {
// 匹配就继续后移
// 匹配就继续后移
if (string.data[i] == pattern.data[j]) {
i++;
j++;
}
// 不匹配就撤回
// 不匹配就撤回
else {
i = i - j + 1;
j = 0;
@@ -61,11 +61,11 @@ int LocateSimple(SequenceString string, SequenceString pattern) {
return -1;
}
// 获取KMP的next数组
// 获取KMP的next数组
int *GetNext(SequenceString string) {
auto *next = (int *) malloc(sizeof(int) * string.length);
next[0] = 0;
// i为当前主串正在匹配的字符位置也就是next数组的索引
// i为当前主串正在匹配的字符位置也就是next数组的索引
int i = 0, j = 0;
while (i < string.length) {
if (j == 0 || string.data[i] == string.data[j]) {
@@ -77,11 +77,11 @@ int *GetNext(SequenceString string) {
return next;
}
// 获取KMP的nextval数组
// 获取KMP的nextval数组
int *GetNextVal(SequenceString string) {
auto *nextval = (int *) malloc(sizeof(int) * string.length);
nextval[0] = 0;
// i为当前主串正在匹配的字符位置也就是next数组的索引
// i为当前主串正在匹配的字符位置也就是next数组的索引
int i = 0, j = 0;
while (i < string.length) {
if (j == 0 || string.data[i] == string.data[j]) {
@@ -102,16 +102,16 @@ int LocateKMP(SequenceString string, SequenceString pattern, const int *next) {
int i = 0, j = 0;
while (i < string.length && j < pattern.length) {
if (j == 0 || string.data[i] == pattern.data[j]) {
// 匹配则继续比较
// 匹配则继续比较
++i;
++j;
} else {
// 模式串右移
// 模式串右移
j = next[j];
}
}
if (j >= pattern.length) {
// 匹配成功
// 匹配成功
return i - pattern.length;
} else {
return -1;
@@ -123,16 +123,16 @@ int LocateKMP(SequenceString string, SequenceString pattern) {
int i = 0, j = 0;
while (i < string.length && j < pattern.length) {
if (j == 0 || string.data[i] == pattern.data[j]) {
// 匹配则继续比较
// 匹配则继续比较
++i;
++j;
} else {
// 模式串右移
// 模式串右移
j = next[j];
}
}
if (j >= pattern.length) {
// 匹配成功
// 匹配成功
return i - pattern.length;
} else {
return -1;

View File

@@ -1,15 +1,15 @@
#include "head.h"
typedef struct {
// 数据
// 数据
element_type *data;
// 栈顶指针
// 栈顶指针
int top_left, top_right;
// 最大容量
// 最大容量
int max_size;
} ShareStack;
// 初始化
// 初始化
bool InitShareStack(ShareStack &stack) {
stack.data = (element_type *) malloc(sizeof(element_type) * MAXSIZE);
stack.top_left = -1;
@@ -44,55 +44,55 @@ ShareStack InitShareStack(int max_size) {
return (ShareStack &) stack;
}
// 判左空
// 判左空
bool EmptyLeftShareStack(ShareStack stack){
return stack.top_left == -1;
}
// 判右空
// 判右空
bool EmptyRightShareStack(ShareStack stack){
return stack.top_right == stack.max_size;
}
// 判满
// 判满
bool FullShareStack(ShareStack stack){
return stack.top_right - stack.top_left == 1;
}
// 左栈长
// 左栈长
int LengthLeftShareStack(ShareStack stack){
return stack.top_left + 1;
}
// 右栈长
// 右栈长
int LengthRightShareStack(ShareStack stack){
return stack.max_size - stack.top_right;
}
// 左进栈
// 左进栈
bool PushLeftShareStack(ShareStack &stack, element_type elem){
if(FullShareStack(stack)){
printf("PushLeftShareStack:栈满无法进栈!\n");
printf("PushLeftShareStack:栈满无法进栈!\n");
return false;
}
stack.data[++stack.top_left] = elem;
return true;
}
// 右进栈
// 右进栈
bool PushRightShareStack(ShareStack &stack, element_type elem){
if(FullShareStack(stack)){
printf("PushRightShareStack:栈满无法进栈!\n");
printf("PushRightShareStack:栈满无法进栈!\n");
return false;
}
stack.data[--stack.top_right] = elem;
return true;
}
// 左出栈
// 左出栈
element_type PopLeftShareStack(ShareStack &stack){
if(EmptyLeftShareStack(stack)){
printf("PopLeftShareStack:栈空无法出栈!\n");
printf("PopLeftShareStack:栈空无法出栈!\n");
return DEFAULTELEM;
}
element_type elem = stack.data[stack.top_left];
@@ -100,10 +100,10 @@ element_type PopLeftShareStack(ShareStack &stack){
return elem;
}
// 右出栈
// 右出栈
element_type PopRightShareStack(ShareStack &stack){
if(EmptyLeftShareStack(stack)){
printf("PopRightShareStack:栈空无法出栈!\n");
printf("PopRightShareStack:栈空无法出栈!\n");
return DEFAULTELEM;
}
element_type elem = stack.data[stack.top_right];
@@ -111,19 +111,19 @@ element_type PopRightShareStack(ShareStack &stack){
return elem;
}
// 读取左首部
// 读取左首部
element_type TopLeftShareStack(ShareStack stack){
if(EmptyLeftShareStack(stack)){
printf("PopLeftShareStack:栈空无法出栈!\n");
printf("PopLeftShareStack:栈空无法出栈!\n");
return DEFAULTELEM;
}
return stack.data[stack.top_left];
}
// 读取右首部
// 读取右首部
element_type TopRightShareStack(ShareStack stack){
if(EmptyLeftShareStack(stack)){
printf("TopRightShareStack:栈空无法出栈!\n");
printf("TopRightShareStack:栈空无法出栈!\n");
return DEFAULTELEM;
}
return stack.data[stack.top_right];

66
Code/Code/head/sort.h Normal file
View File

@@ -0,0 +1,66 @@
#include "head.h"
// 直接插入排序
bool StraightInsertSort(LinearTable table) {
// 循环从第二个开始
for (int i = 1; i < table.length; i++) {
// 若当前元素小于前面一个,即小于已排序序列的最大值,则要对当前元素排序
if (table.data[i] < table.data[i - 1]) {
// 向前遍历是否有比当前元素大的,若有则插到当前元素后面
int temp = table.data[i];
// 不断后移元素
int j;
for (j = i - 1; j >= 0 && table.data[j] > temp; j--) {
table.data[j + 1] = table.data[j];
}
// 将temp插入这个空处
table.data[j + 1] = temp;
}
}
return true;
}
// 折半插入排序
bool BinaryInsertSort(LinearTable table) {
// 定义指针
int i, j, low, high, mid;
elem_type temp;
// 依次将元素插入到前面的排序序列
for (i = 1; i < table.length; i++) {
temp = table.data[i];
// 设置折半查找的范围即从0到当前元素前一个元素
low = 0;
high = i - 1;
while (low <= high) {
// 取中间点
mid = (low + high) / 2;
// 查左子表
if (table.data[mid] > table.data[0])
high = mid - 1;
// 查右子表
else
low = mid + 1;
}
for (j = i - 1; j > high; j--) {
// 后移一位,空出插入位置
table.data[j + 1] = table.data[j];
}
table.data[j + 1] = temp;
}
}
// 希尔排序
bool ShellSort(LinearTable table) {
int j;
// 设置步长
for (int group = table.length / 2; group > 0; group /= 2) {
for (int i = group; i < table.length; i++) {
elem_type temp = table.data[i];
for (j = i; j >= group && temp < table.data[j - group]; j -= group) {
table.data[j] = table.data[j - group];
}
table.data[j] = temp;
}
}
return true;
}

View File

@@ -1,75 +1,75 @@
#include "head.h"
// 线索二叉树结点
// 线索二叉树结点
typedef struct ThreadBinaryTreeNode {
// 数据
// 数据
element_type data;
// 左右孩子结点
// 左右孩子结点
ThreadBinaryTreeNode *left_child, *right_child;
// 左右线索指针
// 左右线索指针
int left_tag, right_tag;
} ThreadBinaryTreeNode, *ThreadBinaryTree;
// 中序遍历线索化
// 中序遍历线索化
bool InOrderThreadBinaryTree(ThreadBinaryTree &tree, ThreadBinaryTree &pre) {
if (tree != nullptr) {
// 递归线索化左子树
// 递归线索化左子树
InOrderThreadBinaryTree(tree->left_child, pre);
// 左子树为空,建立前驱线索
// 左子树为空,建立前驱线索
if (tree->left_child == nullptr) {
// 将左子树指向前驱
// 将左子树指向前驱
tree->left_child = pre;
tree->left_tag = 1;
}
// 当其前驱不为空且前驱的右子树为空
// 当其前驱不为空且前驱的右子树为空
if (pre != nullptr && pre->right_child == nullptr) {
// 将前驱的后继线索指向当前结点
// 将前驱的后继线索指向当前结点
pre->right_child = tree;
pre->right_tag = 1;
}
// 将当前结点设为前驱结点
// 将当前结点设为前驱结点
pre = tree;
// 递归线索化右子树
// 递归线索化右子树
InOrderThreadBinaryTree(tree->right_child, pre);
}
return true;
}
// 建立中序线索二叉树
// 建立中序线索二叉树
bool CreateInOrderThreadBinaryTree(ThreadBinaryTree tree) {
ThreadBinaryTreeNode *pre = nullptr;
if (tree != nullptr) {
// 线索化二叉树
// 线索化二叉树
InOrderThreadBinaryTree(tree, pre);
// 处理遍历的最后一个结点
// 处理遍历的最后一个结点
pre->right_child = nullptr;
pre->right_tag = 1;
}
return true;
}
// 中序线索二叉树中序序列第一个结点
// 中序线索二叉树中序序列第一个结点
ThreadBinaryTreeNode *FirstInOrderBinaryTreeNode(ThreadBinaryTreeNode *node) {
// 当有左孩子结点
// 当有左孩子结点
while (node->left_tag == 0) {
// 最左下的结点,不一定是叶子结点
// 最左下的结点,不一定是叶子结点
node = node->left_child;
}
return node;
}
// 中序线索二叉树中序序列后继
// 中序线索二叉树中序序列后继
ThreadBinaryTreeNode *NextInOrderBinaryTreeNode(ThreadBinaryTreeNode *node){
// 如果有右孩子结点,则找到其右子树的最左结点
// 如果有右孩子结点,则找到其右子树的最左结点
if(node->right_tag==0){
return FirstInOrderBinaryTreeNode(node->right_child);
}
else
// 若有后继线索则直接返回线索
// 若有后继线索则直接返回线索
return node->right_child;
}
// 中序遍历线索二叉树
// 中序遍历线索二叉树
bool InOrderThreadBinaryTree(ThreadBinaryTree *tree,bool( *function)(ThreadBinaryTreeNode)){
for(ThreadBinaryTreeNode *node= FirstInOrderBinaryTreeNode(*tree);node != nullptr;node= NextInOrderBinaryTreeNode(node)){
if(!function(*node))
@@ -78,79 +78,79 @@ bool InOrderThreadBinaryTree(ThreadBinaryTree *tree,bool( *function)(ThreadBinar
return true;
}
// 先序遍历线索化
// 先序遍历线索化
bool PreOrderThreadBinaryTree(ThreadBinaryTree &tree, ThreadBinaryTree &pre) {
if (tree != nullptr) {
// 左子树为空,建立前驱线索
// 左子树为空,建立前驱线索
if (tree->left_child == nullptr) {
// 将左子树指向前驱
// 将左子树指向前驱
tree->left_child = pre;
tree->left_tag = 1;
}
// 当其前驱不为空且前驱的右子树为空
// 当其前驱不为空且前驱的右子树为空
if (pre != nullptr && pre->right_child == nullptr) {
// 将前驱的后继线索指向当前结点
// 将前驱的后继线索指向当前结点
pre->right_child = tree;
pre->right_tag = 1;
}
// 将当前结点设为前驱结点
// 将当前结点设为前驱结点
pre = tree;
// 需要判断是否有左孩子
// 需要判断是否有左孩子
if(tree->left_tag==0){
// 递归线索化左子树
// 递归线索化左子树
InOrderThreadBinaryTree(tree->left_child, pre);
}
// 递归线索化右子树
// 递归线索化右子树
InOrderThreadBinaryTree(tree->right_child, pre);
}
return true;
}
// 建立先序线索二叉树
// 建立先序线索二叉树
bool CreatePreOrderThreadBinaryTree(ThreadBinaryTree tree) {
ThreadBinaryTreeNode *pre = nullptr;
if (tree != nullptr) {
// 线索化二叉树
// 线索化二叉树
PreOrderThreadBinaryTree(tree, pre);
// 处理遍历的最后一个结点
// 处理遍历的最后一个结点
pre->right_child = nullptr;
pre->right_tag = 1;
}
return true;
}
// 后序遍历线索化
// 后序遍历线索化
bool PostOrderThreadBinaryTree(ThreadBinaryTree &tree, ThreadBinaryTree &pre) {
if (tree != nullptr) {
// 递归线索化左子树
// 递归线索化左子树
InOrderThreadBinaryTree(tree->left_child, pre);
// 递归线索化右子树
// 递归线索化右子树
InOrderThreadBinaryTree(tree->right_child, pre);
// 左子树为空,建立前驱线索
// 左子树为空,建立前驱线索
if (tree->left_child == nullptr) {
// 将左子树指向前驱
// 将左子树指向前驱
tree->left_child = pre;
tree->left_tag = 1;
}
// 当其前驱不为空且前驱的右子树为空
// 当其前驱不为空且前驱的右子树为空
if (pre != nullptr && pre->right_child == nullptr) {
// 将前驱的后继线索指向当前结点
// 将前驱的后继线索指向当前结点
pre->right_child = tree;
pre->right_tag = 1;
}
// 将当前结点设为前驱结点
// 将当前结点设为前驱结点
pre = tree;
}
return true;
}
// 建立后序线索二叉树
// 建立后序线索二叉树
bool CreatePostOrderThreadBinaryTree(ThreadBinaryTree tree) {
ThreadBinaryTreeNode *pre = nullptr;
if (tree != nullptr) {
// 线索化二叉树
// 线索化二叉树
PreOrderThreadBinaryTree(tree, pre);
// 处理遍历的最后一个结点
// 处理遍历的最后一个结点
pre->right_child = nullptr;
pre->right_tag = 1;
}

View File

@@ -1,29 +1,29 @@
#include "head.h"
// 双亲表示法
// 结点
// 双亲表示法
// 结点
typedef struct {
element_type data;
// 双亲位置
// 双亲位置
int parent;
} ParentTreeNode;
// 数
// 数
typedef struct {
// 数组
// 数组
ParentTreeNode* data;
// 长度
// 长度
int length;
// 最大容量
// 最大容量
int max_length;
} ParentTree;
// 孩子兄弟表示法
// 结点
// 孩子兄弟表示法
// 结点
typedef struct ChildSiblingTreeNode {
// 数据
// 数据
element_type data;
// 第一个孩子
// 第一个孩子
struct ChildSiblingTreeNode *frist_child;
// 下一个兄弟
// 下一个兄弟
struct ChildSiblingTreeNode *next_sibling;
} ChildSiblingTreeNode, *ChildSiblingTree;

View File

@@ -3,6 +3,7 @@
int main()
{
//SequenceListTest();
LinkListTest();
// LinkListTest();
SortTest();
return 0;
}

View File

@@ -1,4 +1,4 @@
// 测试
// ²âÊÔ
#include <iostream>
#include "../head/sequence_list.h"
#include "../head/link_list.h"
@@ -16,6 +16,7 @@
#include "../head/tree.h"
#include "../head/graph.h"
#include "../head/search.h"
#include "../head/sort.h"
using namespace std;
@@ -56,4 +57,16 @@ bool LinkListTest() {
printf("?????%d", GetLengthLinkList(list));
printf("%c???%d", '3', LocateLinkList(list, '3'));
return true;
}
bool SortTest(){
LinearTable table;
int a[3] = {2,4,1};
table.data = a;
table.length = 3;
StraightInsertSort(table);
printf("%d", table.data[0]);
printf("%d", table.data[1]);
printf("%d", table.data[2]);
return true;
}

View File

@@ -41,9 +41,11 @@
也称为折半插入排序,是对直接插入排序的优化,在寻找插入位置时使用二分查找的方式。
当data[mid]==data[i]时为了保证算法的稳定性会继续在mid所指位置右边寻找插入位置。
$data[mid]==data[i]$时,为了保证算法的稳定性,会继续在$mid$所指位置右边寻找插入位置。
当low>high时停止折半查找并将[low,i-1]内的元素全部右移并把元素值赋值到low所指的位置。
$low>high$时停止折半查找,并将$[low,i-1]$内的元素全部右移,并把元素值赋值到$low$所指的位置。
折半插入排序是找到位置了后一起移动元素,而直接插入排序是边查找边排序。
#### 二分插入排序的性能
@@ -51,15 +53,17 @@
二分插入排序是稳定的。
比起直接插入排序,比较关键字的次数减少,移动元素的次数没变,所以总体时间复杂度为$O(n^2)$。
比起直接插入排序,比较关键字的次数减少为$O(n\log_2n)$,移动元素的次数没变,所以总体时间复杂度为$O(n^2)$。
### 希尔排序
又称缩小增量排序。
#### 希尔排序的过程
希尔排序也是对直接插入排序的优化。直接插入排序对于基本有序的序列排序效果较好,所以就希望序列能尽可能基本有序。从而希尔排序的思想就是先追求表中元素部分有序,然后逐渐逼近全局有序。
先将整个待排序元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的),分别进行直接插入排序,然后缩小增量重复上述过程,直到增量为1
先将整个待排序元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的),分别进行直接插入排序(或者折半插入排序),然后缩小增量重复上述过程,直到增量为$1$。每次对比只对比两个元素进行插入交换
增量序列的选择建议是第一趟选择元素个数的一半,后面不断缩小到原来的一半。