标签:
之前老师就讲过了选择法和冒泡法,之后又提到了插入法和排序法,今天做了一个小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
标签:
原文地址:http://blog.csdn.net/cd18333612683/article/details/51339566