网上做网站怎么做下拉菜单做ppt好的网站有哪些内容
网上做网站怎么做下拉菜单,做ppt好的网站有哪些内容,大学部门宣传视频创意,wordpress请求接口数据库排序确实要总结一下#xff0c;因为下面写完就忘了上面的一些排序是什么了了#xff0c;最好就是先写一个简单的描述#xff0c;用来快速回顾。考研之前的知识点类似#xff0c;进过三次变换之后排序变成什么样。请问符合什么排序。所以我们要知道这些排序的特点默认都是从…排序确实要总结一下因为下面写完就忘了上面的一些排序是什么了了最好就是先写一个简单的描述用来快速回顾。考研之前的知识点类似进过三次变换之后排序变成什么样。请问符合什么排序。所以我们要知道这些排序的特点默认都是从小到大排序的讲前置知识点对于每一个可以排序的值它不止是一个int还有其他内容所以提前定义。#pragma once typedef int keytype; typedef struct { keytype key; int* data; }element; typedef struct { element* data; int lenght; }sorttable; void insertsort(sorttable* table);排序的依据就是这些元素之间的关键字key插入排序算法本身和两个优化思路稳定性 稳定原始算法简单描述一下就是按从小到大遍历如果这个值小于前一个值的话就临时存储这个值然后令i-1的值为j就让这个i值的数一直和j的值比如果还是小的话就让对应的j指的值后移并使j到下一个数直到i的值是大的就让临时值放在j1的位置。如果这个值本来就是大于i-1的那就不用动代码部分:void insertsort(sorttable* table) { element temp; for (int i 1; i table-lenght; i) { if (table-data[i].key table-data[i - 1].key) { temp table-data[i]; int j i - 1; for (j i - 1; j 0 table-data[j].key temp.key; j--) { table-data[j 1] table-data[j]; } table-data[j 1] temp; } } for (int i 0; i table-lenght; i) { printf(%d , table-data[i].key); } } 交换排序和选择排序的思路是一样的所以就直接省略直接就用交换排序冒泡排序稳定性稳定简单描述一下冒泡排序之神降下了他的仁慈让饱受排序之苦之人献上最甜美的佳酿狗头。就是双重遍历外层负责为内层加上一个范围的限制而已内层负责比较和交换如果发现j的值比j1的值还要大就交换他们j后这个值指的就是这个较大值了然后重复比较使得最大的值放在最后面。下一次的范围就排除最后一个重复这个操作知道只剩下一个数。代码部分这里简单贴一下只是用int数组的int a[] { 5,9,77,36,8,45 }; int t 0; int n sizeof(a) / sizeof(a[0]); for (int i 0; i n; i) { for (int j 0; j n - i - 1; j) { if (a[j 1] a[j]) { t a[j]; a[j] a[j 1]; a[j 1] t; } } } for (int i 0; i n; i) { printf(%d , a[i]); } }优化思路如果只有后面的极少部分是乱序的但是前面都是有序的那么每次遍历的话就会浪费时间所以提出以下优化。如果遍历一遍发现没有交换就说明这次遍历的范围已经是有序的就不用再排了直接break跳出循环。⼀次优化是为了避免数组有序void test02() { int a[] { 1,2,3,4,5,6 }; int t 0; int n sizeof(a) / sizeof(a[0]); for (int i 0; i n; i) { /**/ int issort 1; for (int j 0; j n - i - 1; j) { if (a[j 1] a[j]) { t a[j]; a[j] a[j 1]; a[j 1] t; /**/ issort 0; } } /**/ if (issort) { break; } } for (int i 0; i n; i) { printf(%d , a[i]); } }/**/下面的对比有变化的部分优化二这个是解决只是中间或较前面是乱的但是其他是有序的情况下我们加入了一个挡板每当做出一次交换挡板就会指向i1的部分挡板最后就会停留在最后一次交换即说明挡板的后面就是有序的减少了遍历的次数。否能够确定出已经有序部分和⽆序部分的边界void test03() { int a[] { 5,9,77,36,8,45 }; int t 0; int n sizeof(a) / sizeof(a[0]); int index 0; do { index 0; for (int i 0; i n - 1; i) { if (a[i] a[i 1]) { t a[i]; a[i] a[i 1]; a[i 1] t; index i 1; } } n index; } while (index 0); for (int i 0; i sizeof(a) / sizeof(a[0]) ; i) { printf(%d , a[i]); } }快速排序稳定性不稳定双边快速排序运用递归的思想定义三个指针即left,right,和pivot每次都将pivot做为分割pivot前面的是比pivot小的pivot后面的是比pivot大的直到分成分成最小的两个一组就是left大于等于right的时候更加具体一点的步骤就是每次都取这个区间的第一个(或者最后中间随机)作为pivot首先先让right指的值与pivot的值作比较如果大的话就继续right--如果发现比他小的话就是已经发现了一个不应该放在右边的东西然后使得left的和pivot的比如果是小的话就一直如果是大的话就和right的交换又从新从right比较开始。如果一直都是left直到rightleft也没有关系因为还是 要进行left和pivot的交换还是会使这个较小值放在pivot的左边代码部分代码部分分成三个部分对外接口的部分递归部分核心函数的部分对外接口的部分仅仅提供要排序的表的部分作为参数void quickSortV1(SortTable* table) { quickSort1(table, 0, table-length - 1); }递归部分自顶向下的递归思想不断把一个大人物拆成小任务先排pivot左边的部分在排pivot右边的部分直到这个区间只剩下一个元素就是排好了用代码表示就是leftright;static void quickSort2(SortTable *table, int startIndex, int endIndex) { if (startIndex endIndex) { return; } // 找到犄点 int pivot partitionSingle(table, startIndex, endIndex); quickSort2(table, startIndex, pivot - 1); quickSort2(table, pivot 1, endIndex); }核心函数思路就是上面描述的部分static int partitionSingle(SortTable *table, int startIndex, int endIndex) { keyType tmpValue table-data[startIndex].key; int mark startIndex; for (int i startIndex 1; i endIndex; i) { if (table-data[i].key tmpValue) { mark; swapElement(table-data[i], table-data[mark]); } } swapElement(table-data[startIndex], table-data[mark]); return mark; }单边快速排序算法思路:就是分格点边成了mark指针保证mark 的左边比他小他的右边比他大然后对mark和pivot的进行交换。具体步骤令i不断往前如果是大于mark的就继续走如果发现比他小的就先让mark 这时mark指的值已经是确定比pivot大的而i当前指的值一定是比pivot小的然后交换mark和i 的值那么mark一直指的就是小于等于pivot的i最后遍历完之后在再交换mark和pivot指向的是第一个最后一个随机就可以保证前面的是小的后面的是大的。后面重复这个操作。对外接口void quickSortV2(SortTable* table) { quickSort2(table, 0, table-length - 1); }递归的部分static void quickSort2(SortTable *table, int startIndex, int endIndex) { if (startIndex endIndex) { return; } // 找到犄点 int pivot partitionSingle(table, startIndex, endIndex); quickSort2(table, startIndex, pivot - 1); quickSort2(table, pivot 1, endIndex); }核心部分;static int partitionSingle(SortTable *table, int startIndex, int endIndex) { keyType tmpValue table-data[startIndex].key; int mark startIndex; for (int i startIndex 1; i endIndex; i) { if (table-data[i].key tmpValue) { mark; swapElement(table-data[i], table-data[mark]); } } swapElement(table-data[startIndex], table-data[mark]); return mark; }堆排序从1开始稳定性不稳定简单描述一下堆排序就是依赖类似完全二叉树的逻辑结构分成小顶堆根小于左右孩子和大顶堆根大于左右孩子。这里默认写一个小顶堆。主要逻辑就是分为建堆和排序。堆的操作可以分为创造 释放 插入 提取代码部分创造在内存中开辟一个空间并初始化一个完全二叉树miniheap* creatheap(int n) { miniheap* heap malloc(sizeof(miniheap)); if (heap NULL) { return NULL; } heap-data malloc(sizeof(keyType) * (n 1)); // 完全二叉树从1号下标开始存储 if (heap-data NULL) { free(heap); return NULL; } heap-capcity n; heap-len 0; return heap; }释放释放空间void releasemini(miniheap* heap) { if (heap) { if (heap-data) { free(heap-data); heap-data NULL; } free(heap); } }插入逻辑上插入元素的时候都是插在了对应完全二叉树的最后一个节点这就导致了插入这个元素可能会导致这个不符合完全二叉树的性质。这时候我们就要内置一个上浮函数让这个值放到他正确位置。逻辑如果他比他的爸还要小那么久交换他和他的爸的位置。void insert(miniheap* heap, keyType e) { /*少考虑了边界的情况就是如果已经满了就不能插入了*/ if (heap-len 1 heap-capcity) { return; } heap-data[heap-len] e; up(heap, heap-len); }static void up(miniheap* heap,int k) { /*既然是上浮那么就是找爸,这个k就是这个根节点的下标*/ keyType t; while (k 1heap-data[k] heap-data[k / 2]) { t heap-data[k]; heap-data[k] heap-data[k / 2]; heap-data[k / 2] t; k / 2; } } 提取这里我们都是从小到大的排序所以我们要提取根元素但是直接取走逻辑上根的位置就位空了。所以我们将最后的元素放在第一个保证他们是完整的然后用下沉函数调整位置。下沉函数选择这两个孩子中较小的那一个然后交换。keyType extra(miniheap* heap) { if (heap-len 0) { return 0; } keyType ret heap-data[1]; heap-data[1] heap-data[heap-len--]; shiftDown(heap, 1); return ret; } /*上浮*/ static void up(miniheap* heap,int k) { /*既然是上浮那么就是找爸,这个k就是这个根节点的下标*/ keyType t; while (k 1heap-data[k] heap-data[k / 2]) { t heap-data[k]; heap-data[k] heap-data[k / 2]; heap-data[k / 2] t; k / 2; } } 归并排序稳定性不稳定简单描述一下利用递归的思想不断分成最小的部分仅有一个元素然后合并左右集合。集合合并的方法分别产生左右两个集合的临时数组和分别的指针指向他们的第一个元素比较大小然后不小的那个放在原来的数组空间上小的那个数组向前移动。直到其中一个数组遍历完了另一个数组是已经排好序了那么直接将这个数组放在原来的数组后面就行了。代码部分#includemergesort.h #includestdlib.h /*递归*/ static void merge(SortTable* table, int left,int mid,int right) { /* *1.脑测步骤先开两个数组 别用i j 表示是两个数组当前指的下标 * * */ int n1 mid - left 1; int n2 right - mid; Element* leftauto malloc(sizeof(Element) * n1); Element* rightauto malloc(sizeof(Element) * n2); if (leftauto NULL) { return ; } if (rightauto NULL) { free(leftauto); return ; } for (int i 0; i n1; i) { //因为这个不只是前面的那一个 leftauto[i] table-data[lefti]; } for (int i 0; i n2; i) { rightauto[i] table-data[mid 1 i]; } int i 0; int j 0; int k left; while (i n1 j n2) { if (leftauto[i].key rightauto[j].key) { table-data[k] leftauto[i]; } else { table-data[k] rightauto[j]; } k; } while (i n1) { table-data[k] leftauto[i]; } while (j n2) { table-data[k] rightauto[j]; } free(leftauto); free(rightauto); } /*这里拆分已经做好然后就是合并的环节了*/ static void loop(SortTable* table, int left, int right) { if (left right) { return; } int mid (left right) / 2; loop(table, left, mid); loop(table, mid 1, right); merge(table, left, mid, right); } /*归并排序递归和并*/ void mergeSort(SortTable* table) { loop(table, 0, table-length - 1); } 统计基数排序上面的排序都是基于比较稳定性不稳定这个只能处理整数简单描述一下就是对于一组要排序的数遍历一次建立一个数组每遍历到一个数就让这个数对应下标的数组最后遍历这个数组输出结果即可。桶排序和统计排序差不多就是把数组改成了一个个区间桶下期更新二分查找和哈希表喜欢的话记得点点关注你的一个关注就是我更新的动力。