C#学习笔记 自己写排序

Swap交换函数

	private static void Swap(ref T t1, ref T t2) {
		T tmp = t1;
		t1 = t2;
		t2 = tmp;
	}

选择排序

	#region 选择排序算法
	public static void SelectSort(T[] arr) {
		for (int i = 0; i < arr.Length - 1; i++) {
			int minIndex = i;   // 最终最小值的位置
			for (int j = i + 1; j < arr.Length; j++)
				if (arr[j].CompareTo(arr[minIndex]) < 0)    // arr[j] < arr[minIndex]
					minIndex = j;
			Swap(ref arr[i], ref arr[minIndex]);
		}
	}
	#endregion

冒泡排序

	#region 冒泡排序算法
	public static void BubbleSort(T[] arr) {
		for (int i = 1; i < arr.Length; i++) {          // i表示第i趟
			for (int j = 0; j < arr.Length - i; j++) {
				if (arr[j].CompareTo(arr[j + 1]) > 0)   // arr[j] > arr[j + 1]
					Swap(ref arr[j], ref arr[j + 1]);
			}
		}
	}
	#endregion

插入排序

	#region 插入排序算法
	public static void InsertSort(T[] arr) {
		T tmp;
		int i, j;
		for (i = 1; i < arr.Length; i++) {          // 前i - 1个已排好序
			tmp = arr[i];                           // 要插入的元素 tmp
			for (j = i; j >= 1 && tmp.CompareTo(arr[j - 1]) < 0; j--)    // if tmp < arr[j - 1]
				arr[j] = arr[j - 1];
			arr[j] = tmp;
		}
	}
	#endregion

快速排序

	#region 快速排序算法
	public static void QuickSort(T[] arr) {
		QuickSort(arr, 0, arr.Length - 1);
	}

	private static void Median3(T[] arr, int left, int right) {
		int center = (left + right) / 2;    // 找中位数基准
		if (arr[left].CompareTo(arr[center]) > 0) Swap(ref arr[left], ref arr[center]);
		if (arr[center].CompareTo(arr[right]) > 0) Swap(ref arr[center], ref arr[right]);
		if (arr[left].CompareTo(arr[center]) > 0) Swap(ref arr[left], ref arr[center]);
		// 此时, arr[left] <= arr[center] <= arr[right]
		Swap(ref arr[center], ref arr[right]);      // 将基准放置最右端
	}

	private static void QuickSort(T[] arr, int left, int right) {
		//Console.WriteLine(left + " " + right);
		if (left >= right) return;
		if (right - left >= 3) Median3(arr, left, right);      // 找出基准, 并放置最后

		int l = left - 1, h = right;
		while (true) {
			while (arr[++l].CompareTo(arr[right]) < 0) ;
			while (h > left && arr[--h].CompareTo(arr[right]) > 0) ;
			if (l >= h) break;
			Swap(ref arr[l], ref arr[h]);
		}
		Swap(ref arr[l], ref arr[right]);   // 将基准放到简单位置

		QuickSort(arr, left, l - 1);    // 递归解决左边
		QuickSort(arr, l + 1, right);   // 递归解决右边
	}
	#endregion

归并排序

	#region 归并排序算法
	public static void MergeSort(T[] arr) {
		T[] t = new T[arr.Length];
		MergeSort(arr, t, 0, arr.Length - 1);
	}
	private static void MergeSort(T[] arr, T[] t, int ll, int rr) {
		// 用来把区间[ll, rr]的数排序
		if (ll >= rr) return;
		int mid = (ll + rr) >> 1;
		MergeSort(arr, t, ll, mid);
		MergeSort(arr, t, mid + 1, rr);
		int p = ll, q = mid + 1;
		for (int i = ll; i <= rr; i++)
			if (q > rr || (p <= mid && arr[p].CompareTo(arr[q]) < 0))   // q Copyed 或 (p !Copyed && arr[p] < arr[q])
				t[i] = arr[p++];
			else
				t[i] = arr[q++];
		for (int i = ll; i <= rr; i++) arr[i] = t[i];
	}
	#endregion

希尔排序

	#region 希尔排序算法
	public static void ShellSort(T[] arr) {
		List<int> sedArr = GetSedgewick(arr.Length);    // 获取初始的增量sedArr[0]不能超过排序列长度

		T tmp;
		int Si = 0, D, i, j;
		for (D = sedArr[Si]; D > 0; D = sedArr[++Si]) {    // 选定D为每次的希尔增量(间隔)
			for (i = D; i < arr.Length; i++) {  // 插入排序
				tmp = arr[i];
				for (j = i; j >= D && tmp.CompareTo(arr[j - D]) < 0; j -= D)     // 间隔D之前的数排序, if tmp < arr[j - D]
					arr[j] = arr[j - D];
				arr[j] = tmp;
			}
		}
	}

	// Sedgewick增量序列
	// D=9*4^i-9*2^i+1 或 4^(i+2)-3*2^(i+2)+1 , i>=0
	// 稍微变一下形:D=9*(2^(2i)-2^i)+1 或 2^(2i+4)-3*2^(i+2)+1 , i>=0
	private static List<int> GetSedgewick(int len) {
		List<int> sed = new List<int>();
		sed.Add(0);
		for (int i = 0; ; i++) {
			long tmp = 9 * ((1 << 2 * i) - (1 << i)) + 1;
			if (tmp <= len)
				sed.Insert(0, (int)tmp);
			tmp = (1 << (2 * i + 4)) - 3 * (1 << i + 2) + 1;
			if (tmp <= len)
				sed.Insert(0, (int)tmp);
			else
				break;
		}
		return sed;
	}
	#endregion

堆排序

	#region 堆排序算法
	public static void HeapSort(T[] arr) {
		for (int i = arr.Length / 2 - 1; i >= 0; i--)   // 建立最大堆
			PercDown(arr, i, arr.Length);

		// 开始堆排序, 与选择排序一样, 每次选择未排序中的最大者
		for (int i = arr.Length - 1; i > 0; i--) {
			// 选取最大者
			Swap(ref arr[0], ref arr[i]);
			PercDown(arr, 0, i);    // 
		}

	}
	private static void PercDown(T[] arr, int P, int N) {
		// PercDown[A, i, N]实现对A[]中的前N个元素从第i个元素开始向下迁移调整为最大堆过程
		int parent, child;

		T X = arr[P];   // 取出根结点存放的值
		for (parent = P; (parent * 2 + 1) < N; parent = child) {
			child = parent * 2 + 1;
			if ((child != N - 1) && (arr[child].CompareTo(arr[child + 1]) < 0))
				child++;        // child指向左右孩子中的较大者

			if (X.CompareTo(arr[child]) >= 0) break;    // 找到了合适位置
			else        // 下滤X
				arr[parent] = arr[child];
		}
		arr[parent] = X;
	}
	#endregion

基数排序

// c++实现

void RadixSort(vector<int>& nums) {
    int n = nums.size();
    int maxVal = INT_MIN;
    for (int i = 0; i < n; ++i) maxVal = max(maxVal, nums[i]);

    int exp = 1;
    vector<int> buf(n);
    while (maxVal >= exp) {
        vector<int> cnt(10);
        for (int i = 0; i < n; ++i) {
            int digit = (nums[i] / exp) % 10;
            cnt[digit]++;  // 统计每个数字的数量
        }
        // 向后得到每个同步到坐标定位区间, cnt[9] = n
        for (int i = 1; i < 10; i++) cnt[i] += cnt[i - 1];

        for (int i = n - 1; i >= 0; --i) {
            // 将得到新的数组buf为桶排序de一趟后的结果
            int digit = (nums[i] / exp) % 10;
            buf[cnt[digit] - 1] = nums[i];
            cnt[digit]--;
        }
        copy(buf.begin(), buf.end(), nums.begin());  // 将nums = buf
        exp *= 10;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值