当前位置: 首页 > news >正文

数据结构算法(C语言)

目录

排序

冒泡排序

快速排序

插入排序

选择排序

归并排序

希尔排序

堆排序

排序

冒泡排序

void bubbleSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {for (int j = 0; j < n-i-1; j++) {if (arr[j] > arr[j+1]) {// 交换 arr[j] 和 arr[j+1]int temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}
}

快速排序

void quickSort(int arr[], int low, int high) {if (low < high) {// 分区操作int pivot = partition(arr, low, high);// 递归排序两部分quickSort(arr, low, pivot - 1);quickSort(arr, pivot + 1, high);}
}int partition(int arr[], int low, int high) {int pivot = arr[high];int i = low - 1;for (int j = low; j <= high - 1; j++) {if (arr[j] < pivot) {i++;// 交换 arr[i] 和 arr[j]int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}// 交换 arr[i+1] 和 arr[high]int temp = arr[i+1];arr[i+1] = arr[high];arr[high] = temp;return i + 1;
}

插入排序

void insertionSort(int arr[], int n) {for (int i = 1; i < n; i++) {int key = arr[i];int j = i - 1;// 将比key大的元素后移while (j >= 0 && arr[j] > key) {arr[j+1] = arr[j];j--;}// 插入keyarr[j+1] = key;}
}

选择排序

void selectionSort(int arr[], int n) {for (int i = 0; i < n-1; i++) {// 找到最小元素的位置int min_idx = i;for (int j = i+1; j < n; j++) {if (arr[j] < arr[min_idx]) {min_idx = j;}}// 交换最小元素和当前元素if (min_idx != i) {int temp = arr[i];arr[i] = arr[min_idx];arr[min_idx] = temp;}}
}

归并排序

void mergeSort(int arr[], int l, int r) {if (l < r) {// 计算中间点int m = l + (r - l) / 2;// 递归排序左右两部分mergeSort(arr, l, m);mergeSort(arr, m + 1, r);// 合并已排序的两部分merge(arr, l, m, r);}
}void merge(int arr[], int l, int m, int r) {int i, j, k;int n1 = m - l + 1;int n2 = r - m;// 创建临时数组int L[n1], R[n2];// 复制数据到临时数组for (i = 0; i < n1; i++) L[i] = arr[l + i];for (j = 0; j < n2; j++) R[j] = arr[m + 1 + j];// 合并临时数组回原数组i = 0; j = 0; k = l;while (i < n1 && j < n2) {if (L[i] <= R[j]) {arr[k] = L[i];i++;} else {arr[k] = R[j];j++;}k++;}// 复制剩余元素while (i < n1) {arr[k] = L[i];i++;k++;}while (j < n2) {arr[k] = R[j];j++;k++;}
}

希尔排序

void shellSort(int arr[], int n) {// 初始增量为n/2,逐渐减半for (int gap = n / 2; gap > 0; gap /= 2) {// 对每个增量进行插入排序for (int i = gap; i < n; i++) {int temp = arr[i];int j;// 对相隔gap的元素进行比较和移动for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {arr[j] = arr[j - gap];}// 插入temparr[j] = temp;}}
}

堆排序

void heapSort(int arr[], int n) {// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个个从堆中取出元素for (int i = n - 1; i > 0; i--) {// 交换堆顶(最大值)和当前元素int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 重新调整堆heapify(arr, i, 0);}
}void heapify(int arr[], int n, int i) {int largest = i;    // 初始化根int l = 2 * i + 1;  // 左子节点int r = 2 * i + 2;  // 右子节点// 如果左子节点比根大if (l < n && arr[l] > arr[largest]) {largest = l;}// 如果右子节点比根大if (r < n && arr[r] > arr[largest]) {largest = r;}// 如果最大的不是根if (largest != i) {int temp = arr[i];arr[i] = arr[largest];arr[largest] = temp;// 递归调整受影响的子树heapify(arr, n, largest);}
}

查找

在一棵树中找到一个字符,输出查找时经过的结点序列

链表

合并两个有序单链表

Node* mergeLists(Node* l1, Node* l2) {// 创建虚拟头节点,避免处理空链表的边界情况Node dummy = {0, NULL};// 尾指针始终指向新链表的最后一个节点Node* tail = &dummy;// 同时遍历两个链表,直到其中一个遍历完while (l1 && l2) {// 比较当前节点值,选择较小的节点接入新链表if (l1->data < l2->data) {tail->next = l1;      // 将l1接入新链表l1 = l1->next;        // l1指针后移} else {tail->next = l2;      // 将l2接入新链表l2 = l2->next;        // l2指针后移}tail = tail->next;        // 尾指针后移}// 处理剩余节点:直接将非空链表的剩余部分接入新链表尾部tail->next = l1 ? l1 : l2;// 返回虚拟头节点的下一个节点,即合并后链表的头节点return dummy.next;
}

数组

合并两个有序数组

void mergeArrays(int* arr1, int m, int* arr2, int n) {// i指向arr1的有效元素末尾(从m-1开始)int i = m - 1;// j指向arr2的末尾(从n-1开始)int j = n - 1;// k指向合并后数组的末尾(总长度m+n-1)int k = m + n - 1;// 从后向前遍历两个数组,将较大元素放入合并位置while (i >= 0 && j >= 0) {if (arr1[i] > arr2[j]) {// arr1的当前元素更大,放入k位置arr1[k] = arr1[i];i--;  // 移动arr1的指针} else {// arr2的当前元素更大或相等,放入k位置arr1[k] = arr2[j];j--;  // 移动arr2的指针}k--;  // 合并位置指针前移}// 处理arr2中可能剩余的元素(arr1剩余元素无需处理,已在正确位置)while (j >= 0) {arr1[k] = arr2[j];  // 将arr2剩余元素复制到arr1前面j--;k--;}
}

有序数组倒置

void reverseArray(int* arr, int n) {int left = 0;           // 左指针初始化为数组起始位置int right = n - 1;      // 右指针初始化为数组末尾位置while (left < right) {  // 当左指针小于右指针时循环// 交换左右指针所指元素int temp = arr[left];arr[left] = arr[right];arr[right] = temp;left++;             // 左指针右移right--;            // 右指针左移}
}

判断二叉树是否为二叉搜索树

bool isBST(Node* root, Node* min, Node* max) {if (root == NULL) return true;  // 空树是BST// 检查当前节点是否在(min, max)范围内if ((min != NULL && root->data <= min->data) || (max != NULL && root->data >= max->data)) {return false;}// 递归检查左右子树:左子树<root<右子树return isBST(root->left, min, root) && isBST(root->right, root, max);
}// 调用示例
bool checkBST(Node* root) {return isBST(root, NULL, NULL);
}

#define MAX_SIZE 100typedef struct {int data[MAX_SIZE];  // 存储栈元素的数组int top;             // 栈顶指针
} Stack;// 初始化栈
void initStack(Stack* s) {s->top = -1;         // 空栈的栈顶指针为-1
}// 判断栈是否为空
bool isEmpty(Stack* s) {return s->top == -1;
}// 判断栈是否已满
bool isFull(Stack* s) {return s->top == MAX_SIZE - 1;
}// 入栈操作
bool push(Stack* s, int value) {if (isFull(s)) return false;  // 栈满则操作失败s->data[++(s->top)] = value;  // 先移动栈顶指针,再存入值return true;
}// 出栈操作
bool pop(Stack* s, int* value) {if (isEmpty(s)) return false;  // 栈空则操作失败*value = s->data[(s->top)--];  // 先取出值,再移动栈顶指针return true;
}// 获取栈顶元素
bool peek(Stack* s, int* value) {if (isEmpty(s)) return false;  // 栈空则操作失败*value = s->data[s->top];      // 仅获取值,不移动指针return true;
}

括号匹配

bool isValid(char* s) {Stack stack;init(&stack);for (int i = 0; s[i] != '\0'; i++) {char c = s[i];if (c == '(' || c == '[' || c == '{') {push(&stack, c);  // 左括号入栈} else {int top;if (!pop(&stack, &top)) return false;  // 栈空则匹配失败if ((c == ')' && top != '(') || (c == ']' && top != '[') || (c == '}' && top != '{')) {return false;  // 括号类型不匹配}}}return isEmpty(&stack);  // 栈空表示所有括号匹配成功
}

用两个栈实现队列

typedef struct {Stack s1, s2;  // s1用于入队,s2用于出队
} MyQueue;// 初始化队列
MyQueue* myQueueCreate() {MyQueue* q = (MyQueue*)malloc(sizeof(MyQueue));init(&q->s1);init(&q->s2);return q;
}// 入队操作
void myQueuePush(MyQueue* q, int x) {push(&q->s1, x);
}// 出队操作
int myQueuePop(MyQueue* q) {if (isEmpty(&q->s2)) {while (!isEmpty(&q->s1)) {int val;pop(&q->s1, &val);push(&q->s2, val);}}int val;pop(&q->s2, &val);return val;
}

相关文章:

  • 从golang的sync.pool到linux的slab分配器
  • python中从队列里取出全部元素的两种写法
  • vue注册自定义指令
  • CSS 预处理器与工具
  • MCP 技术完全指南:微软开源项目助力 AI 开发标准化学习
  • PostgreSQL 的扩展pageinspect
  • github中main与master,master无法合并到main
  • 408第一季 - 数据结构 - 树与二叉树II
  • Python实例题:Python计算微积分
  • C++ 中的编译期计算(Compile-Time Computation)
  • Nature子刊:16S宏基因组+代谢组学联动,借助MicrobiomeGS2建模揭示IBD代谢治疗新靶点
  • 《经济学原理》第9版第6章供给、需求和政府政策
  • 历史数据分析——唐山港
  • 探索NoSQL注入的奥秘:如何消除MongoDB查询中的前置与后置条件
  • Unity | AmplifyShaderEditor插件基础(第五集:简易膨胀shader)
  • Android LinearLayout、FrameLayout、RelativeLayout、ConstraintLayout大混战
  • 向 AI Search 迈进,腾讯云 ES 自研 v-pack 向量增强插件揭秘
  • 【基础算法】差分算法详解
  • 在 Windows 11 或 10 上将 Visual Studio Code 添加到系统路径
  • 永恒之蓝(CVE-2017-0146)详细复现
  • 一个网站怎么做软件好用/上海搜索seo
  • 网站设计公司推荐奇点网络/百度ocpc怎么优化
  • 怎样免费做书画网站/营销型公司网站建设
  • 企业英文网站制作/网络营销专业可以干什么工作
  • 网站建设 微信营销/网站优化排名易下拉系统
  • 微网站自己可以做么/公司做网站需要多少钱