之前老师就讲过了选择法和冒泡法,之后又提到了插入法和排序法,今天做了一个小DEMO,对比了一下四种方法的效率,当然看了很多大牛也博客,其实算法还设计了时间复杂度和空间复杂度,对于这两个概念,我只能从表面上进行理解,其中涉及到了很多数学的问题,所以就不展开写了。
这部分知识比较新,而且内容比较多,所以打算单独另外总结一遍博客,来详细的总结一下这个方法~
<span style="font-size: 24px;"> </span><span style="font-size:14px;">private List<int> a = new List<int>(); private HashSet<int> hs = new HashSet<int>(); /// <summary> /// 生成随机数 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnGenerate_Click(object sender, EventArgs e) { for (int i = listBox1.Items.Count - 1; i >= 0; i--) { listBox1.Items.RemoveAt(i); } //清空HashSet hs.Clear(); int count = 0; try //获取生成个数 { count = Int32.Parse(txtCount.Text); } catch (Exception ex) { MessageBox.Show("个数有误"); } Random r = new Random((int)DateTime.Now.Ticks); //以当前时间为时间随机种子 //生成随机数 for (int i = 0; hs.Count < count; i++) { hs.Add(r.Next(10000));//最多可以生成9999个数 } a = hs.ToList<int>(); //HashSet转为List //a.Sort(); // 排序 //输出随机数到列表 for (int i = 0; i < a.Count; i++) { this.listBox1.Items.Add(a[i]); } }</span>
<span style="font-size:14px;">/// <summary> /// 插入法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button3_Click(object sender, EventArgs e) { //哈希表转整数数组 int[] s = hs.ToArray(); DateTime time1 = DateTime.Now; int count = Int32.Parse(txtCount.Text); for (int i = 1; i < count ; i++) //外层循环,控制执行(n-1)趟排序 { if (s[i] > s[i - 1]) //判断大小,决定是否需要交换 { int temp = s[i]; //如果需要交换,则将待排序记录放入临时变量中 int j = 0; for (j = i - 1; j >= 0 && temp > s[j]; j--) //内层循环,在有序序列中从后往前比较,找到待排序记录在有序列中位置(位置空出) { s[j + 1] = s[j]; //将有序记录往后移 } s[j + 1] = temp; //将临时变量中的值放入正确位置,即空出的位置 } } DateTime time2 = DateTime.Now; textBox3.Text = DateDiff(time1, time2); for (int i = listBox1.Items.Count - 1; i >= 0; i--) { listBox1.Items.RemoveAt(i); } for (int i = 0; i < s.Length; i++) { this.listBox1.Items.Add(s[i]); } }</span>
<span style="font-size:14px;"> /// <summary> /// 快速排序法 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button4_Click(object sender, EventArgs e) { //哈希表转整数数组 int[] s = hs.ToArray(); DateTime time1 = DateTime.Now; int low=0; //记录目标数组的起始位置 int high=s.Length-1; //记录目标数组的结束位置 QuickSortFunction(s, low, high); DateTime time2 = DateTime.Now; textBox4.Text = DateDiff(time1, time2); for (int i = listBox1.Items.Count - 1; i >= 0; i--) { listBox1.Items.RemoveAt(i); } for (int i = 0; i < s.Length; i++) { this.listBox1.Items.Add(s[i]); } } /// <summary> /// 快速排序过程 /// </summary> /// <param name="array">数组</param> /// <param name="low">低位目标数组下标</param> /// <param name="high">高位目标数组下边</param> private static void QuickSortFunction(int[] array, int low, int high) { int keyValuePosition; //记录关键值的下标 //当传递的目标数组含有两个以上的元素时,进行递归调用。(即:当传递的目标数组只含有一个元素时,此趟排序结束) if (low < high) { keyValuePosition = keyValuePositionFunction(array, low, high); //获取关键值的下标(快排的核心) QuickSortFunction(array, low, keyValuePosition - 1); //递归调用,快排划分出来的左区间 QuickSortFunction(array, keyValuePosition + 1, high); //递归调用,快排划分出来的右区间 } } /// <summary> /// 找出关键值位置 /// </summary> /// <param name="array">数组</param> /// <param name="low">低位下标</param> /// <param name="high">高位下标</param> /// <returns>关键值下标</returns> private static int keyValuePositionFunction(int[] array, int low, int high) { int i = low; //记录目标数组的起始位置(后续动态的左侧下标) int j = high; //记录目标数组的结束位置(后续动态的右侧下标) int keyValue = array[low]; //数组的第一个元素作为关键值 int temp; //当 (左侧动态下标 == 右侧动态下标) 时跳出循环 while (i< j) { while (i < j && array[j] > keyValue) //必须先从右边开始,逐渐向左移动,直至找到<=keyValue的下标 { j--; } while (i < j && array[j] <= keyValue) //从左边开始,直至找到>=keyValue的下标 { i++; } if(i < j) //如果leftIndex < rightIndex,则交换左右动态下标所指定的值;当leftIndex==rightIndex时,跳出整个循环 { temp = array[i]; array[i] = array[j]; array[j] = temp; } } //当左右两个动态下标相等时(即:左右下标指向同一个位置),此时便可以确定keyValue的准确位置 temp = keyValue; if (temp < array[j]) //当keyValue < 左右下标同时指向的值,将keyValue与rightIndex - 1指向的值交换,并返回rightIndex - 1 { array[low] = array[j - 1]; array[j - 1] = temp; return j - 1; } else //当keyValue >= 左右下标同时指向的值,将keyValue与rightIndex指向的值交换,并返回rightIndex { array[low] = array[j]; array[j] = temp; return j; } }</span>
总结这四个算法,花了一天的时间,虽然画图的时候也会嫌麻烦,但是画过之后,印象真的深刻了,知道自己哪里不懂,哪里还需要补充学习,最开始选择法和排序法是在学习C语言的课上,那会真的觉得没意思,但是现在自己静下心来自学了插入法和快速排序法之后,觉得算法真的是一门艺术,一大堆的数在等着你来给他们排排队,有一种世界被我掌控的感觉,说的有些夸张,但是学习中的乐趣只有学进去了才能体会吧,不过我可不是书呆子,真正研究数学的大家也都没有学傻,不管怎样,在心里重新定义了算法,给大家推荐一本书《啊哈!算法!》,通俗易懂,妙趣横生!快速排序就是跟啊哈磊学的,下边是链接,不谢,叫我雷锋好吗~
点我:
https://yunpan.cn/cPD8d8L2tTqeK 访问密码 08d7