class Sort
{
/// <summary>
/// 插入排序:顺序的将待排序的记录插入到已排序的记录的适当位置,当已排序记录个数与顺序表中数据的个数相等时,排序完毕
/// 时间复杂度:最好的情况下,数据已经是有序的O(n),最坏的情况下是O(n^2),平均时间复杂度O(n^2)
/// </summary>
public void InsertSort(List<int> _asort)
{
for (int i = 1; i < _asort.Count; ++i)
{
int temp = 0;
if (_asort[i] < _asort[i - 1])
{
temp = _asort[i];
int j = 0;
for (j = i - 1; j >= 0 && temp < _asort[j]; --j)
{
//移动数组中的元素
_asort[j + 1] = _asort[j];
}
_asort[j + 1] = temp;
}
}
}
/// <summary>
/// 冒泡排序:将相邻的记录关键码进行比较,如后者小于前者数据交换,否则不交换 时间复杂度O(n^2)
/// </summary>
public void BubbleSort(List<int> _bulleList)
{
int tmp=0;
//排序次数
for (int i = 0; i < _bulleList.Count; ++i)
{
//排序
for (int j = 0; j < _bulleList.Count - i - 1; ++j)
{
if (_bulleList[j + 1] < _bulleList[j])
{
tmp = _bulleList[j + 1];
_bulleList[j + 1] = _bulleList[j];
_bulleList[j] = tmp;
}
}
}
}
/// <summary>
/// 选择排序:从待排序数据中,选择最小的关键码与第一个进行交换,再从第二个数据开始,在待排序数据中选择最小的与第二个数据交换,循环
/// 时间复杂度:最好O(1);最坏O(n^2);平均时间复杂度O(n^2)
/// </summary>
public void SelectSort(List<int> _selectList)
{
//记录序号
int t;
for (int i = 0; i < _selectList.Count; ++i)
{
t = i;
int j = 0;
for (j = i + 1; j < _selectList.Count; ++j)
{
if (_selectList[t] > _selectList[j])
{
t = j;
}
}
int temp = _selectList[i];
_selectList[i] = _selectList[t];
_selectList[t] = temp;
}
for (int i = 0; i < _selectList.Count; i++)
{
Console.WriteLine(_selectList[i]);
}
}
/// <summary>
/// 快速排序:以某个关键码作为支点,把数组分成俩部分,一部分数据大于或等于支点关键码,一部分小于支点关键码,然后再进行划分
/// </summary>
/// <param name="_quikList"></param>
public void QuiklySort(List<int> _quikList,int start,int end)
{
if (start < end)
{
int temp = _quikList[start];
int i = start;
int j = end;
while (i < j)
{
while (i < j && _quikList[j] > temp)
--j;
_quikList[i] = _quikList[j];
while (i < j && _quikList[i] <= temp)
++i;
_quikList[j] = _quikList[i];
}
_quikList[i] = temp;
QuiklySort(_quikList, start, i - 1);
QuiklySort(_quikList, i + 1, end);
}
else
return;
}
/// <summary>
/// 堆排序:特殊的树,必须满足一下俩点
/// 1.堆是一个完全二叉树(完全二叉树:除最后一层,其它层的节点个数都是满的,最后一层的节点都靠左排列)
/// 2.堆中每个节点的值,都必须大于或等于其子节点的值(每个节点的值大于或等于其子节点的值称为大顶堆,反之小顶堆)
/// 3.堆的存储:因为堆是完全二叉树,所以用数组进行存储 1 2 3 4 5 6 7 8 9,下标为i的节点,左节点为i*2,右节点为i*2+1
/// 4.堆的操作:(1)添加元素、堆化;(2)删除堆顶元素、堆化
/// </summary>
//建堆
void BuildHeap(List<int> _heapList,int n)
{
//数组小标从零开始
for (int i = n/2; i >=0; --i)
{
Heap(_heapList,n, i);
}
}
//堆化
void Heap(List<int> _heapList,int k,int i)
{
while (true)
{
//堆化的过程是从第一个不是叶子节点的节点开始从下往上堆化
int maxPos = i;
if (i * 2 <= k && _heapList[i] < _heapList[i * 2])
maxPos = i * 2;
if (i * 2 + 1 <= k && _heapList[maxPos] < _heapList[i * 2 + 1])
maxPos = i * 2 + 1;
if (maxPos == i)
break;
Swap(_heapList, i,maxPos);
i = maxPos;
}
}
void Swap(List<int> _heapList,int i,int j)
{
int temp = _heapList[i];
_heapList[i] = _heapList[j];
_heapList[j] = temp;
}
public void HeapSort(List<int> _heapList,int n)
{
//建堆
BuildHeap(_heapList,n);
while (n >= 0)
{
//建堆好的数组,最后一个数据与第一个数据交换位置
Swap(_heapList, 0, n);
--n;
//堆化
Heap(_heapList, n, 0);
}
}
/// <summary>
/// 归并排序:分治思想,时间复杂度O(nlog2n)
/// </summary>
/// <param name="_mergeList"></param>
public void MergeSort(List<int> _mergeList,int n)
{
MSort(_mergeList,0,n-1);
}
void MSort(List<int> _mergeList, int p, int r)
{
if (p >= r) return;
int mid = (p + r) / 2;
//分治
MSort(_mergeList, p, mid);
MSort(_mergeList, mid + 1, r);
//合并
Merge(_mergeList,p, r, mid);
}
void Merge(List<int> _mergeList,int p,int r,int q)
{
int i = p;int j = q + 1;
int[] temp = new int[r-p+1];
int k = 0;
while (i <= q && j <= r)
{
if (_mergeList[i] < _mergeList[j])
temp[k++] = _mergeList[i++];
else
temp[k++] = _mergeList[j++];
}
while (i <= q)
temp[k++] = _mergeList[i++];
while (j <= r)
temp[k++] = _mergeList[j++];
for (int a = 0; a < temp.Length; a++)
_mergeList[p++] = temp[a];
}
}
排序算法总结
最新推荐文章于 2023-04-05 09:51:20 发布