您的位置:首页 > 理论基础 > 数据结构算法

C# 数据结构中 排序算法

2009-07-14 17:46 513 查看
//http://www.hiahia.org/datastructure/paixu/paixu8.4.1-1.htm 参考地址

//按平均时间将排序分为四类:

//(1)平方阶(O(n2))排序
// 一般称为简单排序,例如直接插入、直接选择和冒泡排序;

//(2)线性对数阶(O(nlgn))排序
// 如快速、堆和归并排序;

//(3)O(n1+£)阶排序
// £是介于0和1之间的常数,即0<£<1,如希尔排序;

//(4)线性阶(O(n))排序
// 如桶、箱和基数排序。

namespace ConsoleApplication1
{
public class SortOne
{
public static void Main()
{
int[] t = { 12, 1, 3, 4, 7 };
//t = InsertSort(t);
//t = BInsertSort(t);
//t = BubbleSort1(t);
//t = BubbleSort2(t);
//t = QuickSort(t, 0, t.Length - 1);

//int[] temp = new int[t.Length];
//t = MergeSort(t, temp, 0, t.Length - 1);
//t = MergeSort1(t, 0, t.Length - 1);
t = DirectSort(t);
for (int i = 0; i < t.Length; i++)
Console.Write(t[i].ToString() + " ");
Console.Read();
}
#region 插入排序
//直接插入排序 时间复杂度 O(n^2) 使用附加控件 1
//思路:不停的插入,比较之前的数据
public static int[] InsertSort(int[] T)
{
if (T.Length <= 1) return T;
int temp;
for (int i = 1; i < T.Length; i++)
{
if (T[i] < T[i - 1])
{
temp = T[i];
int j;
for (j = i - 1; j >= 0 && temp < T[j]; j--)
{
T[j + 1] = T[j];
}
T[j + 1] = temp;
}
}
return T;
}
//直接插入排序 时间复杂度 O(n^2) 使用附加控件 1
//思路:不停的插入比较之前的数据;插入地址用折半查找法定位
public static int[] BInsertSort(int[] T)
{
if (T.Length <= 1) return T;
int temp;
for (int i = 1; i < T.Length; i++)
{
if (T[i] < T[i - 1])
{
temp = T[i];
int low = 0, high = i - 1, m = i - 1; //look for the move-index
while (low <= high)
{
m = (low + high) / 2;
if (T[m] > T[i]) high = m - 1;
else low = m + 1;
}
for (int j = i - 1; j >= m && j < T.Length - 1; j--)
{
T[j + 1] = T[j];
}
T[m] = temp;
}
}
return T;
}
#endregion

#region 冒泡排序
//冒泡排序 时间复杂度 O(n^2) 不使用新的空间
//思路: 逐次比较,轻的冒泡上浮
public static int[] BubbleSort1(int[] T)
{
int Count = T.Length;
for (int i = 0; i < Count - 1; i++)
{
bool exchange = false;
for (int j = i + 1; j < Count; j++)
{
if (T[i] > T[j])
{
T[i] ^= T[j];
T[j] ^= T[i];
T[i] ^= T[j];
exchange = true;
}
}
if (!exchange) return T;
}
return T;
}

public static int[] BubbleSort2(int[] T)
{
int Count = T.Length;
bool exchange = true;
while (Count >= 0 && exchange)
{
exchange = false;
for (int i = 0; i < Count - 1; i++)
{
if (T[i] > T[i + 1])
{
T[i] ^= T[i + 1];
T[i + 1] ^= T[i];
T[i] ^= T[i + 1];
exchange = true;
}
}
Count--;
}
return T;
}
#endregion

#region 希尔排序 缩小增量排序,也属于插入排序的方法 ,时间效益上有较大的改进
//先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录'基本有序',再对全体记录进行一次直接插入排序
private static void ShellInsert(int[] T, int dk)
{
int temp;
//对顺序表L做一趟希尔插入排序,前后记录的位置增量为dk,而不是之前默认的1;相隔dk的比较
for (int i = dk; i < T.Length; i++)
{
if (T[i] > T[i - dk])
{
int j;
temp = T[i];
for (j = i - dk; j >= 0 && T[j] > T[i]; j -= dk)
{
T[j + dk] = T[j];
}
T[j + dk] = temp;
}
}
}
public static int[] ShellSort(int[] T, int[] dks)
{//按照dk中的数据进行比较
for (int k = 0; k < dks.Length; k++)
ShellInsert(T, dks[k]);//demo:dks 的数据 为: 5,3,1;其中的数据需要猜测计算,最后一个一定为1
return T;
}
#endregion

#region 快速排序 对冒泡排序的改进
// 通过一趟排序将待排记录分割成独立的2部分,其中一部分记录的关键字比另一部分的关键字小,则可分别对这2部分继续进行排序,已达到整个序列有序
//一般默认将T[0]做为 开始的区间轴 pivot;小的关键字放在他之前,反之放在之后,之后定位pivot
//递归 以pivot为界限的 余下的2个区间
private static int QuickSortPartition(int[] T, int low, int high) //一次排序,可以将 pivot放在正确的位置,左右子相对有序,左子一定小于右子
{
int temp;
if (low < T.Length)
temp = T[low];
else return low - 1; //low index out of range
while (low < high)
{
while (low < high && T[high] > temp)
--high;
T[low] = T[high];
while (low < high && T[low] < temp)
++low;
T[high] = T[low];

}
T[low] = temp;
return low;
}
public static int[] QuickSort(int[] T, int low, int high) //递归调用
{
if (low < high)
{
int pLoc = QuickSortPartition(T, low, high);
QuickSort(T, 0, pLoc - 1);//left
QuickSort(T, pLoc + 1, high);//right
}
return T;
}
#endregion

#region 选择排序
//每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后,直到全部记录排序完毕。
//n(n-1)/2=0(n2)
//直接选择排序
public static int[] DirectSort(int[] T)
{
if (T.Length <= 1)
return T;
for (int i = 0; i < T.Length; i++)
{
int temp = T[i];
int min=i;
for ( int k = i; k < T.Length; k++)
{
if (temp >= T[k])
{
temp = T[k];
min = k;
}//get the least data in k...n
}
T[min] = T[i];
T[i] = temp;
}
return T;
}
#endregion

#region 归并排序
//设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],
//先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。
private static void Merge(int[] T, int[] Temp, int low, int m, int high)
{
int start = low;
int i = low, j = m + 1;
while (i <= m && j <= high)
{
Temp[start++] = T[i] < T[j] ? T[i++] : T[j++];
}
while (i <= m)
{
Temp[start++] = T[i++];
}
while (j <= high)
{
Temp[start++] = T[j++];
}
while (low <= high)// 合并回去到 数组 T
{
T[low] = Temp[low];
low++;
}
}
public static int[] MergeSort(int[] T, int[] Temp, int low, int high)
{
if (low < high)
{
int m = (low + high) / 2;
MergeSort(T, Temp, low, m);
MergeSort(T, Temp, m + 1, high);
Merge(T, Temp, low, m, high);
}
return T;
}
//dynamic malloc array length
private static void Merge1(int[] T, int low, int m, int high)//内部分配 临时数组大小
{
int start = low;
int i = low, j = m + 1; int p = 0;
int[] Temp = new int[high - low + 1];
while (i <= m && j <= high)
{
Temp[p++] = T[i] < T[j] ? T[i++] : T[j++];
}
while (i <= m)
{
Temp[p++] = T[i++];
}
while (j <= high)
{
Temp[p++] = T[j++];
}
for (int index = 0; low <= high; index++)// 合并回去到 数组 T
{
T[low] = Temp[index];
low++;
}
Temp = null;
}

public static int[] MergeSort1(int[] T, int low, int high)
{
if (low < high)
{
int m = (low + high) / 2;
MergeSort1(T, low, m);
MergeSort1(T, m + 1, high);
Merge1(T, low, m, high);
}
return T;
}
#endregion
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: