mirror of
https://github.com/Didnelpsun/CS408.git
synced 2026-02-08 05:14:48 +08:00
更新排序
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "head.h"
|
||||
|
||||
// 块链串结点
|
||||
// ¿éÁ´´®½áµã
|
||||
typedef struct LinkStringNode {
|
||||
// 数据
|
||||
// Êý¾Ý
|
||||
char *data;
|
||||
// 指针
|
||||
// Ö¸Õë
|
||||
LinkStringNode *next;
|
||||
} LinkStringNode, *LinkString;
|
||||
|
||||
|
||||
@@ -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();
|
||||
@@ -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;
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
66
Code/Code/head/sort.h
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -3,6 +3,7 @@
|
||||
int main()
|
||||
{
|
||||
//SequenceListTest();
|
||||
LinkListTest();
|
||||
// LinkListTest();
|
||||
SortTest();
|
||||
return 0;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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$。每次对比只对比两个元素进行插入交换。
|
||||
|
||||
增量序列的选择建议是第一趟选择元素个数的一半,后面不断缩小到原来的一半。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user