330 lines
6.9 KiB
C
330 lines
6.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#endif
|
|
|
|
int MAX = 100000;
|
|
|
|
// 二叉排序树节点创建
|
|
struct TreeNode
|
|
{
|
|
int val;
|
|
int idx;
|
|
struct TreeNode *left;
|
|
struct TreeNode *right;
|
|
};
|
|
|
|
// 顺序查找
|
|
int Linear_Search(int arr[], int size, int target)
|
|
{
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
if (arr[i] == target)
|
|
{
|
|
// 返回目标元素的索引
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// 未找到目标元素
|
|
return -1;
|
|
}
|
|
|
|
// 冒泡排序
|
|
void Bubble_Sort_With_Index(int arr[], int index[], int size)
|
|
{
|
|
for (int i = 0; i < size - 1; ++i)
|
|
{
|
|
int swapped = 0;
|
|
for (int j = 0; j < size - 1 - i; ++j)
|
|
{
|
|
if (arr[j] > arr[j + 1])
|
|
{
|
|
int t = arr[j];
|
|
arr[j] = arr[j + 1];
|
|
arr[j + 1] = t;
|
|
int ti = index[j];
|
|
index[j] = index[j + 1];
|
|
index[j + 1] = ti;
|
|
swapped = 1;
|
|
}
|
|
}
|
|
if (!swapped)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 二分查找
|
|
int Binary_Search(int arr[], int size, int target)
|
|
{
|
|
// 二分查找
|
|
int left = 0;
|
|
int right = size - 1;
|
|
while (left <= right)
|
|
{
|
|
int mid = left + (right - left) / 2;
|
|
if (arr[mid] == target)
|
|
{
|
|
// 返回目标元素的索引
|
|
return mid;
|
|
}
|
|
else if (arr[mid] < target)
|
|
{
|
|
left = mid + 1;
|
|
}
|
|
else
|
|
{
|
|
right = mid - 1;
|
|
}
|
|
}
|
|
|
|
// 未找到目标元素
|
|
return -1;
|
|
}
|
|
|
|
// 分块查找
|
|
int Block_Search(int arr[], int size, int target)
|
|
{
|
|
// 计算分块大小
|
|
int blockSize = (int)sqrt(size);
|
|
int start = 0;
|
|
int end = blockSize - 1;
|
|
|
|
// 分块查找
|
|
while (start < size)
|
|
{
|
|
if (arr[end] >= target)
|
|
{
|
|
for (int i = start; i <= end && i < size; i++)
|
|
{
|
|
if (arr[i] == target)
|
|
{
|
|
// 返回目标元素的索引
|
|
return i;
|
|
}
|
|
}
|
|
|
|
// 未找到目标元素
|
|
return -1;
|
|
}
|
|
start += blockSize;
|
|
end += blockSize;
|
|
if (end >= size)
|
|
{
|
|
end = size - 1;
|
|
}
|
|
}
|
|
|
|
// 未找到目标元素
|
|
return -1;
|
|
}
|
|
|
|
// 二叉排序树节点创建
|
|
struct TreeNode *BST_new(int val, int idx)
|
|
{
|
|
struct TreeNode *p = (struct TreeNode *)malloc(sizeof(struct TreeNode));
|
|
p->val = val;
|
|
p->idx = idx;
|
|
p->left = NULL;
|
|
p->right = NULL;
|
|
return p;
|
|
}
|
|
|
|
// 二叉排序树节点插入
|
|
struct TreeNode *BST_insert(struct TreeNode *root, int val, int idx)
|
|
{
|
|
if (!root)
|
|
{
|
|
return BST_new(val, idx);
|
|
}
|
|
struct TreeNode *cur = root;
|
|
while (1)
|
|
{
|
|
// 小于当前节点,向左子树查找
|
|
if (val < cur->val)
|
|
{
|
|
if (cur->left)
|
|
{
|
|
cur = cur->left;
|
|
}
|
|
else
|
|
{
|
|
cur->left = BST_new(val, idx);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 大于当前节点,向右子树查找
|
|
else if (val > cur->val)
|
|
{
|
|
if (cur->right)
|
|
{
|
|
cur = cur->right;
|
|
}
|
|
else
|
|
{
|
|
cur->right = BST_new(val, idx);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 等于当前节点,返回当前节点的索引
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
return root;
|
|
}
|
|
|
|
// 二叉排序树节点释放
|
|
void BST_free(struct TreeNode *root)
|
|
{
|
|
if (!root)
|
|
{
|
|
return;
|
|
}
|
|
BST_free(root->left);
|
|
BST_free(root->right);
|
|
free(root);
|
|
}
|
|
|
|
// 二叉排序树节点查找
|
|
int BST_Search(struct TreeNode *root, int target)
|
|
{
|
|
while (root)
|
|
{
|
|
if (target == root->val)
|
|
{
|
|
// 返回目标元素的索引
|
|
return root->idx;
|
|
}
|
|
if (target < root->val)
|
|
{
|
|
// 目标元素小于当前节点,向左子树查找
|
|
root = root->left;
|
|
}
|
|
else
|
|
{
|
|
// 目标元素大于当前节点,向右子树查找
|
|
root = root->right;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
#ifdef _WIN32
|
|
system("chcp 65001 > nul");
|
|
SetConsoleOutputCP(65001);
|
|
SetConsoleCP(65001);
|
|
#endif
|
|
|
|
// 输入整数的个数
|
|
printf("请输入整数的个数(不超过 %d):", MAX);
|
|
int n;
|
|
scanf("%d", &n);
|
|
while (n < 1 || n > MAX)
|
|
{
|
|
printf("输入的个数不合法!\n");
|
|
scanf("%d", &n);
|
|
}
|
|
|
|
// 输入整数
|
|
int nums[n];
|
|
printf("请输入 %d 个整数:\n", n);
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
scanf("%d", &nums[i]);
|
|
}
|
|
|
|
// 复制排序数组,并记录索引
|
|
int sortedArr[n];
|
|
int indexArr[n];
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
sortedArr[i] = nums[i];
|
|
indexArr[i] = i;
|
|
}
|
|
Bubble_Sort_With_Index(sortedArr, indexArr, n);
|
|
|
|
// 打印排序后的数组
|
|
printf("排序后的数组元素为:");
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
printf("%d ", sortedArr[i]);
|
|
}
|
|
printf("\n");
|
|
|
|
while (true)
|
|
{
|
|
// 查找目标元素
|
|
int target;
|
|
int index;
|
|
printf("请输入要查找的整数:");
|
|
scanf("%d", &target);
|
|
|
|
// 选择查找方法
|
|
printf("请选择查找方法:\n");
|
|
printf("1. 线性查找\n");
|
|
printf("2. 二分查找(数组需有序)\n");
|
|
printf("3. 分块查找(数组需有序)\n");
|
|
printf("4. 二叉搜索树查找\n");
|
|
printf("5. 退出程序\n");
|
|
|
|
// 读取用户选择
|
|
int choice;
|
|
scanf("%d", &choice);
|
|
|
|
switch (choice)
|
|
{
|
|
case 1:
|
|
index = Linear_Search(nums, n, target);
|
|
break;
|
|
case 2:
|
|
{
|
|
int pos = Binary_Search(sortedArr, n, target);
|
|
index = (pos != -1) ? indexArr[pos] : -1;
|
|
break;
|
|
}
|
|
case 3:
|
|
{
|
|
int pos = Block_Search(sortedArr, n, target);
|
|
index = (pos != -1) ? indexArr[pos] : -1;
|
|
break;
|
|
}
|
|
case 4:
|
|
{
|
|
struct TreeNode *root = NULL;
|
|
for (int i = 0; i < n; ++i)
|
|
{
|
|
root = BST_insert(root, nums[i], i);
|
|
}
|
|
index = BST_Search(root, target);
|
|
BST_free(root);
|
|
break;
|
|
}
|
|
case 5:
|
|
return 0;
|
|
default:
|
|
printf("无效的选择,请重新选择。\n");
|
|
continue;
|
|
}
|
|
|
|
// 输出查找结果
|
|
if (index != -1)
|
|
{
|
|
printf("找到了,目标元素的索引为:%d\n", index);
|
|
}
|
|
else
|
|
{
|
|
printf("未找到目标元素。\n");
|
|
}
|
|
}
|
|
} |