算法与数据结构-单向链表的直接插入排序和快速排序

序言

本文将介绍单向链表的直接插入排序快速排序


1. 单链表进行直接插入排序


1.1 直接插入排序函数

/* 直接插入排序 */
//本文中使用不带头结点的链表

struct listNode *ListInsertSort(struct listNode *L)
{
    struct listNode *originListNode;   //原链表的节点指针
    struct listNode *nodeScan;         //节点扫描指针,新链表的当前节点
    struct listNode *preNode;          //新链表的前一节点
    struct listNode *newNode;          //原链表节点的临时指针

    //分离原链表
    originListNode = L -> next;

    //原链表/无序链表第一个节点作为新链表/有序链表第一个元素,L仍指向第一个节点
    L -> next = NULL;

    //遍历无序链表
    while (originListNode != NULL)
    {
        //在有序链表中寻找合适的插入位置
        preNode = NULL;
        newNode = originListNode;
        nodeScan = L;              //每次都要从有序链表的第一个节点开始扫描
        while ((nodeScan != NULL) && (nodeScan -> data < newNode -> data))
        {
            preNode = nodeScan;
            nodeScan = nodeScan -> next;
        }

        //无序链表遍历
        originListNode = originListNode -> next;

        //节点插入到L之前或preNode和nodeScan之间
        if (nodeScan == L)
            L = newNode;
        else
            preNode -> next = newNode;

        newNode -> next = nodeScan;

        //返回排序后链表首指针
        return L;
    }
}

//在有序链表中寻找合适插入位置也可写成:
for (newNode = originListNode, nodeScan = L; (nodeScan != NULL) && (nodeScan -> data) < (newNode -> data); preNode = nodeScan, nodeScan = nodeScan -> next);


1.2 完整示例程序



#include <stdio.h>
#include <stdlib.h>

//单向链表定义
typedef struct LNode
{
    int data;
    struct LNode *next;
}LNode;

typedef LNode *LinkList;


//函数声明
LinkList CreatLink(int num);
LinkList LinkInsertSort(LinkList head);
void PrintLink(LinkList head);


/* 链表创建 */
LinkList CreatLink(int num)
{
    int data;

    //p指向当前链表中最后一个结点,q指向准备插入的结点。
    LinkList head = NULL, rearNode = NULL, newNode;

    for (int i = 0; i < num; i++)
    {
        scanf("%d", &data);
        newNode = (LinkList)malloc(sizeof(LNode));
        newNode -> data = data;
        newNode -> next = NULL;
        if (i == 0)                 //头结点
        {
            head = newNode;
        }
        else
        {
            rearNode -> next = newNode;
        }
        rearNode = newNode;
    }
    return head;
}

/*************************************
功能: 直接插入排序
    数组直接插入排序:待排序数组 + 排序后数组
    链表直接插入排序:待排序链表 + 排序后链表
***************************************/
LinkList LinkInsertSort(LinkList head)
{
    LinkList originList, nodeScan, preNode, newNode;

    if (head == NULL)
        return head;

    //分离原链表为有序和无序链表
    originList = head -> next;

    //有序链表的第一个节点L指向节点
    head -> next = NULL;

    //遍历无序链表
    while (originList)
    {
        newNode = originList;
        originList = originList -> next;

        preNode = NULL;

        //寻找元素插入位置
        for (nodeScan = head; (nodeScan != NULL) && (nodeScan -> data < newNode -> data); preNode = nodeScan, nodeScan = nodeScan -> next);

        //循环退出表示查找到节点插入的位置
        if (nodeScan == head)
            head = newNode;
        else
            preNode -> next = newNode;

        newNode -> next = nodeScan;
    }

    return head;
}

/* 链表输出函数 */
void PrintLink(LinkList head)
{
    LinkList nodeScan;
    for (nodeScan = head; nodeScan ;nodeScan = nodeScan->next)
    {
        printf("%-3d ", nodeScan->data);
    }
}

int main()
{
    LinkList head;
    int listLen;
    printf("输入链表节点个数:\n");
    scanf("%d", &listLen);
    printf("输入元素值:\n");

    head = CreatLink(listLen);

    head = LinkInsertSort(head);
    printf("排序后:\n");
    PrintLink(head);
    putchar('\n');
    return 0;
}


2. 单链表进行快速排序

/* 首先定义元素搜索函数 */
//返回第pos个节点指针
struct listNode *NodeSearch(struct listNode *L, int pos)


/* 再定义链表元素交换函数 */
//交换两个节点元素值node->data
void ExchangeNode(struct listNode *L, int i, int j)

/* 元素整理 */
int ElementSort(struct listNode *L, int left, int right)
{
    struct listNode *nodeScan;
    struct listNode *tempNode = NULL;

    int pivot = NodeSearch(L, right) -> data;     //基准元素
    int index = left - 1;

    for (int i = left; i < right; i++)
    {
        int data_i = NodeSearch(L, i);
        int data_pivot = NodeSearch(L, pivot);
        if (data_i < data_pivot)
        {
            index++;
            ExchangeNode(L, index, i);
        }
        ExchangeNode(L, index + 1, right);
    }
    return index + 1;
}

/* 快速排序 */
void ListQuickSort(struct listNode *L, int left, int right)
{
    int pivot_index;
    while (left < right)
    {
        pivot_index = ElementSort(L, left, right);
        ListQuickSort(L, left, pivot_index - 1);   //较小元素子数组递归
        ListQuickSort(L, pivot_index + 1, right);  //较大元素子数组递归
    }
}



Acknowledgements:
http://www.cnblogs.com/Camilo/p/3927912.html
http://blog.csdn.net/baidu_35692628/article/details/68952452#t2

2017.08.13

你可能感兴趣的:(算法与数据结构)