数据结构 C 常见的排序算法

“C

#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>

#define TABLE_SIZE 19

/**
 * <key, value> pair.
 */
typedef struct Node{
    int key;
    char value;
}Node, *NodePtr;

/**
 * <key, value> pair.
 */
typedef struct SequentialList{
    int length;
    NodePtr elements;
}SequentialList, *ListPtr;

/**
 * Initialize a data array.
 */
ListPtr initList(int* paraKeys, char* paraValues, int paraLength){
    int i;
    ListPtr resultPtr = (ListPtr)malloc(sizeof(struct SequentialList));
    resultPtr->length = paraLength;
    resultPtr->elements = (NodePtr)malloc(paraLength * sizeof(struct Node));
    for (i = 0; i < paraLength; i ++){
        //printf("setting key for index %d: %d and value: %c\r\n", i, paraKeys[i], paraValues[i]);
        resultPtr->elements[i].key = paraKeys[i];
        resultPtr->elements[i].value = paraValues[i];
    }//Of for i

    return resultPtr;
}

void printList(ListPtr paraPtr) {
    int i;
    printf("(Keys, values)\r\n");
    for (i = 0; i < paraPtr->length; i ++) {
        printf("%d\t", paraPtr->elements[i].key);
    }//Of for i
    printf("\r\n");
    for (i = 0; i < paraPtr->length; i ++) {
        printf("%c\t", paraPtr->elements[i].value);
    }//Of for i
    printf("\r\n");
}

/**
 * Insertion sort. paraPtr->elements[0] does not store a valid data. paraPtr->elements[0].key should
 * be smaller than any valid key.
 */
void insertionSort(ListPtr paraPtr) {
    Node tempNode;
    int j;
    for (int i = 2; i < paraPtr->length; i++) {
        tempNode = paraPtr->elements[i];
        
        //Find the position to insert.
        //At the same time, move other nodes.
        for (j = i - 1; paraPtr->elements[j].key > tempNode.key; j--) {
            paraPtr->elements[j + 1] = paraPtr->elements[j];
        } // Of for j
        
        //Insert.
        paraPtr->elements[j + 1] = tempNode;
    } // Of for i
}

/**
 * Test the method.
 */
void insertionSortTest() {
    int tempUnsortedKeys[] = { -100, 5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = { 'n', 'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 8);

    printf("\r\nBefore insertion sort:\r\n");
    printList(tempList);

    insertionSort(tempList);
    printf("\r\nAfter insertion sort:\r\n");
    printList(tempList);
}

void shellSort(ListPtr paraPtr) {
    Node tempNode;
    int tempJumpArray[] = { 5, 3, 1 };
    int tempJump;
    int p, i, j, k;
    for (i = 0; i < 3; i++) {
        tempJump = tempJumpArray[i];
        for (j = 0; j < tempJump; j++) {
            for (k = j + tempJump; k < paraPtr->length; k += tempJump) {
                tempNode = paraPtr->elements[k];
                // Find the position to insert.
                // At the same time, move other nodes.
                for (p = k - tempJump; p >= 0; p -= tempJump) {
                    if (paraPtr->elements[p].key > tempNode.key) {
                        paraPtr->elements[p + tempJump] = paraPtr->elements[p];
                    } else {
                        break;
                    } // Of if
                } // Of for p

                // Insert.
                paraPtr->elements[p + tempJump] = tempNode;
            } // Of for k
        } // Of for j
    } // Of for i
}

/**
 * Test the method.
 */
void shellSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore shell sort:\r\n");
    printList(tempList);

    shellSort(tempList);
    printf("\r\nAfter shell sort:\r\n");
    printList(tempList);
}


void bubbleSort(ListPtr paraPtr) {
    bool tempSwapped;
    Node tempNode;
    int i, j;
    for (i = paraPtr->length - 1; i > 0; i--) {
        tempSwapped = false;
        for (j = 0; j < i; j++) {
            if (paraPtr->elements[j].key > paraPtr->elements[j + 1].key) {
                // Swap.
                tempNode = paraPtr->elements[j + 1];
                paraPtr->elements[j + 1] = paraPtr->elements[j];
                paraPtr->elements[j] = tempNode;

                tempSwapped = true;
            } // Of if
        } // Of for j

        // No swap in this round. The data are already sorted.
        if (!tempSwapped) {
            printf("Premature.\r\n");
            break;
        } // Of if
    } // Of for i
}// Of bubbleSort

/**
 * Test the method.
 */
void bubbleSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore bubble sort:\r\n");
    printList(tempList);

    shellSort(tempList);
    printf("\r\nAfter bubble sort:\r\n");
    printList(tempList);
}

/**
 * Quick sort recursive.
 */
void quickSortRecursive(ListPtr paraPtr, int paraStart, int paraEnd) {
    int tempPivot, tempLeft, tempRight;
    Node tempNodeForSwap;
    
    // Nothing to sort.
    if (paraStart >= paraEnd) {
        return;
    } // Of if

    tempPivot = paraPtr->elements[paraEnd].key;
    
    tempLeft = paraStart;
    tempRight = paraEnd - 1;

    // Find the position for the pivot.
    // At the same time move smaller elements to the left and bigger one to the
    // right.
    while (true) {
        while ((paraPtr->elements[tempLeft].key < tempPivot) && (tempLeft < tempRight)) {
            tempLeft++;
        } // Of while

        while ((paraPtr->elements[tempRight].key >= tempPivot) && (tempLeft < tempRight)) {
            tempRight--;
        } // Of while

        if (tempLeft < tempRight) {
            // Swap.
            //System.out.println("Swapping " + tempLeft + " and " + tempRight);
            tempNodeForSwap = paraPtr->elements[tempLeft];
            paraPtr->elements[tempLeft] = paraPtr->elements[tempRight];
            paraPtr->elements[tempRight] = tempNodeForSwap;
        } else {
            break;
        } // Of if
    } // Of while

    // Swap
    if (paraPtr->elements[tempLeft].key > tempPivot) {
        tempNodeForSwap = paraPtr->elements[paraEnd];
        paraPtr->elements[paraEnd] = paraPtr->elements[tempLeft];
        paraPtr->elements[tempLeft] = tempNodeForSwap;
    } else {
        tempLeft++;
    } // Of if

    //System.out.print("From " + paraStart + " to " + paraEnd + ": ");
    //System.out.println(this);

    quickSortRecursive(paraPtr, paraStart, tempLeft - 1);
    quickSortRecursive(paraPtr, tempLeft + 1, paraEnd);
}// Of quickSortRecursive

/**
 * Quick sort.
 */
void quickSort(ListPtr paraPtr) {
    quickSortRecursive(paraPtr, 0, paraPtr->length - 1);
}// Of quickSort

/**
 * Test the method.
 */
void quickSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore quick sort:\r\n");
    printList(tempList);

    quickSort(tempList);
    printf("\r\nAfter quick sort:\r\n");
    printList(tempList);
}// Of quickSortTest

/**
 * Selection sort.
 */
void selectionSort(ListPtr paraPtr) {
    Node tempNode;
    int tempIndexForSmallest, i, j;

    for (i = 0; i < paraPtr->length - 1; i++) {
        // Initialize.
        tempNode = paraPtr->elements[i];
        tempIndexForSmallest = i;
        for (j = i + 1; j < paraPtr->length; j++) {
            if (paraPtr->elements[j].key < tempNode.key) {
                tempNode = paraPtr->elements[j];
                tempIndexForSmallest = j;
            } // Of if
        } // Of for j

        // Change the selected one with the current one.
        paraPtr->elements[tempIndexForSmallest] = paraPtr->elements[i];
        paraPtr->elements[i] = tempNode;
    } // Of for i
}

/**
 * Test the method.
 */
void selectionSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore selection sort:\r\n");
    printList(tempList);

    selectionSort(tempList);
    printf("\r\nAfter selection sort:\r\n");
    printList(tempList);
}// Of selectionSortTest

/**
 * Adjust heap.
 */
void adjustHeap(ListPtr paraPtr, int paraStart, int paraLength) {
    Node tempNode = paraPtr->elements[paraStart];
    int tempParent = paraStart;
    int tempKey = paraPtr->elements[paraStart].key;

    for (int tempChild = paraStart * 2 + 1; tempChild < paraLength; tempChild = tempChild * 2 + 1) {
        // The right child is bigger.
        if (tempChild + 1 < paraLength) {
            if (paraPtr->elements[tempChild].key < paraPtr->elements[tempChild + 1].key) {
                tempChild++;
            } // Of if
        } // Of if

        printf("The parent position is %d and the child is %d.  ", tempParent, tempChild);
        if (tempKey < paraPtr->elements[tempChild].key) {
            // The child is bigger.
            paraPtr->elements[tempParent] = paraPtr->elements[tempChild];
            printf("Move %d to position %d.\r\n", paraPtr->elements[tempChild].key, tempParent);
            tempParent = tempChild;
        } else {
            break;
        } // Of if
    } // Of for tempChild

    printf("Move %d to position %d.\r\n", tempNode.key, tempParent);
    paraPtr->elements[tempParent] = tempNode;
}// Of adjustHeap
 
 /**
 * Heap sort.
 */
void heapSort(ListPtr paraPtr) {
    Node tempNode;
    int i;
    // Step 1. Construct the initial heap.
    for (i = paraPtr->length / 2 - 1; i >= 0; i--) {
        adjustHeap(paraPtr, i, paraPtr->length);
    } // Of for i

    // Step 2. Swap and reconstruct.
    for (i = paraPtr->length - 1; i > 0; i--) {
        tempNode = paraPtr->elements[0];
        paraPtr->elements[0] = paraPtr->elements[i];
        paraPtr->elements[i] = tempNode;

        adjustHeap(paraPtr, 0, i);
        printf("Round %d : ", (paraPtr->length - i));
        printList(paraPtr);
    } // Of for i
}// Of heapSort

/**
 * Test the method.
 */
void heapSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore heap sort:\r\n");
    printList(tempList);

    heapSort(tempList);
    printf("\r\nAfter heap sort:\r\n");
    printList(tempList);
}// Of heapSortTest

/**
 * Selection sort.
 */
void mergeSort(ListPtr paraPtr) {
    // Step 1. Allocate space.

    int tempRow; // The current row
    int tempGroups; // Number of groups
    int tempActualRow; // Only 0 or 1
    int tempNextRow = 0;
    int tempGroupNumber;
    int tempFirstStart, tempSecondStart, tempSecondEnd;
    int tempFirstIndex, tempSecondIndex;
    int tempNumCopied;
    int i;
    int tempSize;

    /*
    ListPtr tempMatrix[2];
    int* tempIntArray = (int*)malloc(paraPtr->length * sizeof(int));
    char* tempCharArray = (char*)malloc(paraPtr->length * sizeof(char));
    tempMatrix[0] = paraPtr;
    tempMatrix[1] = initList(tempIntArray, tempCharArray, paraPtr->length);
    */

    Node** tempMatrix = (Node**)malloc(2 * sizeof(Node*));
    tempMatrix[0] = (Node*)malloc(paraPtr->length * sizeof(Node));
    tempMatrix[1] = (Node*)malloc(paraPtr->length * sizeof(Node));
    for (i = 0; i < paraPtr->length; i ++) {
        tempMatrix[0][i] = paraPtr->elements[i];
    }//Of for i

    /*
    Node tempMatrix[2][length];

    // Step 2. Copy data.
    for (i = 0; i < length; i++) {
        tempMatrix[0][i] = data[i];
    } // Of for i
    */

    // Step 3. Merge. log n rounds
    tempRow = -1;
    for (tempSize = 1; tempSize <= paraPtr->length; tempSize *= 2) {
        // Reuse the space of the two rows.
        tempRow++;
        //System.out.println("Current row = " + tempRow);
        tempActualRow = tempRow % 2;
        tempNextRow = (tempRow + 1) % 2;

        tempGroups = paraPtr->length / (tempSize * 2);
        if (paraPtr->length % (tempSize * 2) != 0) {
            tempGroups++;
        } // Of if
        //System.out.println("tempSize = " + tempSize + ", numGroups = " + tempGroups);

        for (tempGroupNumber = 0; tempGroupNumber < tempGroups; tempGroupNumber++) {
            tempFirstStart = tempGroupNumber * tempSize * 2;
            tempSecondStart = tempGroupNumber * tempSize * 2 + tempSize;
            if (tempSecondStart > paraPtr->length - 1) {
                // Copy the first part.
                for (i = tempFirstStart; i < paraPtr->length; i++) {
                    tempMatrix[tempNextRow][i] = tempMatrix[tempActualRow][i];
                } // Of for i
                continue;
            } // Of if
            tempSecondEnd = tempGroupNumber * tempSize * 2 + tempSize * 2 - 1;
            if (tempSecondEnd > paraPtr->length - 1) {
                tempSecondEnd = paraPtr->length - 1;
            } // Of if

            tempFirstIndex = tempFirstStart;
            tempSecondIndex = tempSecondStart;
            tempNumCopied = 0;
            while ((tempFirstIndex <= tempSecondStart - 1)
                    && (tempSecondIndex <= tempSecondEnd)) {
                if (tempMatrix[tempActualRow][tempFirstIndex].key <= tempMatrix[tempActualRow][tempSecondIndex].key) {

                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                    tempFirstIndex++;
                    //System.out.println("copying " + tempMatrix[tempActualRow][tempFirstIndex]);
                } else {
                    tempMatrix[tempNextRow][tempFirstStart
                            + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                    //System.out.println("copying " + tempMatrix[tempActualRow][tempSecondIndex]);
                    tempSecondIndex++;
                } // Of if
                tempNumCopied++;
            } // Of while

            while (tempFirstIndex <= tempSecondStart - 1) {
                tempMatrix[tempNextRow][tempFirstStart
                        + tempNumCopied] = tempMatrix[tempActualRow][tempFirstIndex];
                tempFirstIndex++;
                tempNumCopied++;
            } // Of while

            while (tempSecondIndex <= tempSecondEnd) {
                tempMatrix[tempNextRow][tempFirstStart
                        + tempNumCopied] = tempMatrix[tempActualRow][tempSecondIndex];
                tempSecondIndex++;
                tempNumCopied++;
            } // Of while
        } // Of for groupNumber

    } // Of for tempStepSize

    for (i = 0; i < paraPtr->length; i ++) {
        paraPtr->elements[i] = tempMatrix[tempNextRow][i];
    }//Of for i
}// Of mergeSort

/**
 * Test the method.
 */
void mergeSortTest() {
    int tempUnsortedKeys[] = {5, 3, 6, 10, 7, 1, 9 };
    char tempContents[] = {'i', 't', 'e', 's', 'c', 'f', 'w' };
    ListPtr tempList = initList(tempUnsortedKeys, tempContents, 7);

    printf("\r\nBefore merge sort:\r\n");
    printList(tempList);

    mergeSort(tempList);
    printf("\r\nAfter merge sort:\r\n");
    printList(tempList);
}// Of mergeSortTest
 
 /**
 * The entrance of the program.
 */
int main() {
    //insertionSortTest();
    //shellSortTest();
    //bubbleSortTest();
    //quickSortTest();
    //selectionSortTest();
    //heapSortTest();
    mergeSortTest();
    return 1;
}// Of main

This is the code.”

运行结果

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值