1. 程式人生 > >經典排序演算法的實現(選擇,插入,shell,堆,快速,歸併排序)

經典排序演算法的實現(選擇,插入,shell,堆,快速,歸併排序)

1.選擇排序

//選擇排序
void selectSort(int * arr, int n) {
	for (int i = 0; i < n - 1; i++) {
		int min = arr[i];
		int minPos = i;
		for (int j = i + 1; j < n; j++) {
			if (min > arr[j]) {
				min = arr[j];
				minPos = j;
			}
		}

		int temp = arr[i];
		arr[i] = arr[minPos];
		arr[minPos] = temp;
	}
}


2.插入排序

//插入排序
void insertSort(int * arr, int n) {
	for (int i = 1; i < n; i++) {
		int k = arr[i];
		int j = i - 1;

		while (j >= 0 && arr[j] > k) {
			arr[j+1] = arr[j];
			j--;
		}
		arr[j+1] = k;
	}
}


3.shell排序

//shell排序,優化插排
void shellSort(int * arr, int n) {
	int step = n;
	while (step > 1) {
		step = step / 2;
		for (int i = step; i < n; i++) {
			int temp = arr[i];
			int j = i;
			while (j - step >= 0 && temp <arr[j - step]) {
				arr[j] = arr[j-step];
				j -= step;
			}
			arr[j] = temp;
		}
	}
}


4.堆排序

//堆排序,優化選排
void headJust(int * arr, int start, int n) {
	int temp = arr[start];
	int child = 2 * start + 1;

	while (child < n) {
		if (child+1 < n && arr[child] < arr[child+1]) {
			child++;
		}

		if (temp >= arr[child]) {
			break;
		}

		arr[start] = arr[child];

		start = child;
		child = child * 2 + 1;
	}

	arr[start] = temp;
}

void headSort(int * arr, int n) {
	for (int i = n / 2; i >= 0; i--) {
		headJust(arr, i, n);
	}

	for (int i = 1; i < n; i++) {
		int temp = arr[0];				//首元素與最後元素進行交換
		arr[0] = arr[n-i];
		arr[n-i] = temp;
		headJust(arr, 0, n-i);			//繼續調整為最大堆
	}
}


5.歸併排序

//歸併排序,分而治之
void merge(int * arr, int first, int mid, int last) {
	int i = first, j = mid+1;
	int m = mid, n = last;
	int k = 0;
	int temp[SIZE];
	while (i <= m && j <= n) {
		temp[k++] = (arr[i] <= arr[j])?arr[i++]:arr[j++];
	}

	while (i <= m) {
		temp[k++] = arr[i++];
	}

	while (j <= n) {
		temp[k++] = arr[j++];
	}

	for (int i = 0; i < k; i++) {
		arr[i+first] = temp[i];
	}
}

void mergeSort(int * arr, int start, int end) {
	if (start < end) {
		int mid = (start+end) / 2;
		mergeSort(arr, start, mid);
		mergeSort(arr, mid+1, end);
		merge(arr, start, mid, end);
	}
}




6.快速排序

//快速排序,挖坑填數分治法
void quickSort(int * arr, int left, int right) {
	if (left < right) {
		int i = left;
		int j = right-1;
		int temp = arr[i];

		while (i < j) {
			while (i < j && arr[j] >= temp)
				j--;
			if (i < j) {
				arr[i++] = arr[j];
			}

			while (i < j && arr[i] < temp)
				i++;
			if (i < j) {
				arr[j--] = arr[i];
			}
		}

		arr[i] = temp;
		quickSort(arr, left, i-1);
		quickSort(arr, i+1, right);
	}
}



具體實現如下

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 200


//快速排序,挖坑填數分治法
void quickSort(int * arr, int left, int right) {
    if (left < right) {
        int i = left;
        int j = right;
        int temp = arr[i];

        while (i < j) {
            while (i < j && arr[j] >= temp)
                j--;
            if (i < j) {
                arr[i++] = arr[j];
            }

            while (i < j && arr[i] < temp)
                i++;
            if (i < j) {
                arr[j--] = arr[i];
            }
        }

        arr[i] = temp;
        quickSort(arr, left, i-1);
        quickSort(arr, i+1, right);
    }
}


//歸併排序,分而治之
void merge(int * arr, int first, int mid, int last) {
	int i = first, j = mid+1;
	int m = mid, n = last;
	int k = 0;
	int temp[SIZE];
	while (i <= m && j <= n) {
		temp[k++] = (arr[i] <= arr[j])?arr[i++]:arr[j++];
	}

	while (i <= m) {
		temp[k++] = arr[i++];
	}

	while (j <= n) {
		temp[k++] = arr[j++];
	}

	for (int i = 0; i < k; i++) {
		arr[i+first] = temp[i];
	}
}

void mergeSort(int * arr, int start, int end) {
	if (start < end) {
		int mid = (start+end) / 2;
		mergeSort(arr, start, mid);
		mergeSort(arr, mid+1, end);
		merge(arr, start, mid, end);
	}
}

//堆排序,優化選排
void headJust(int * arr, int start, int n) {
    int temp = arr[start];
    int child = 2 * start + 1;

    while (child < n) {
        if (child+1 < n && arr[child] < arr[child+1]) {
            child++;
        }

        if (temp >= arr[child]) {
            break;
        }

        arr[start] = arr[child];

        start = child;
        child = child * 2 + 1;
    }

    arr[start] = temp;
}

void headSort(int * arr, int n) {
    for (int i = n / 2; i >= 0; i--) {
        headJust(arr, i, n);
    }

    for (int i = 1; i < n; i++) {
        int temp = arr[0];              //首元素與最後元素進行交換
        arr[0] = arr[n-i];
        arr[n-i] = temp;
        headJust(arr, 0, n-i);          //繼續調整為最大堆
    }
}

//shell排序,優化插排
void shellSort(int * arr, int n) {
    int step = n;
    while (step > 1) {
        step = step / 2;
        for (int i = step; i < n; i++) {
            int temp = arr[i];
            int j = i;
            while (j - step >= 0 && temp <arr[j - step]) {
                arr[j] = arr[j-step];
                j -= step;
            }
            arr[j] = temp;
        }
    }
}

//插入排序
void insertSort(int * arr, int n) {
    for (int i = 1; i < n; i++) {
        int k = arr[i];
        int j = i - 1;

        while (j >= 0 && arr[j] > k) {
            arr[j+1] = arr[j];
            j--;
        }
        arr[j+1] = k;
    }
}

//選擇排序
void selectSort(int * arr, int n) {
    for (int i = 0; i < n - 1; i++) {
        int min = arr[i];
        int minPos = i;
        for (int j = i + 1; j < n; j++) {
            if (min > arr[j]) {
                min = arr[j];
                minPos = j;
            }
        }

        int temp = arr[i];
        arr[i] = arr[minPos];
        arr[minPos] = temp;
    }
}

void initialArray(int * arr, int n) {
    for (int i = 0; i < n; i++) {
        arr[i] = rand() % 100 + 1;
    }
}

void printNum(int * arr, int n) {
    for (int i = 0; i < n; i++) {
        if ((i+1) % 10 == 0) {
            putchar('\n');
        } else {
            printf("%d\t", arr[i]);
        }
    }
}

int main(void)
{
    srand((unsigned) time(NULL));
    int num[SIZE];

    printf("選擇排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("選擇排序後:\n");
    selectSort(num, SIZE);
    printNum(num, SIZE);

    printf("插入排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("插入排序後:\n");
    insertSort(num, SIZE);
    printNum(num, SIZE);

    printf("shell排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("shell排序後:\n");
    shellSort(num, SIZE);
    printNum(num, SIZE);

    printf("堆排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("堆排序後:\n");
    headSort(num, SIZE);
    printNum(num, SIZE);


    printf("歸併排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("歸併排序後:\n");
    mergeSort(num, 0, SIZE-1);
    printNum(num, SIZE);

    printf("快速排序前:\n");
    initialArray(num, SIZE);
    printNum(num, SIZE);
    printf("快速排序後:\n");
    quickSort(num, 0, SIZE-1);
    printNum(num, SIZE);


    return 0;
}