C语言 排序算法 - 数据结构学习笔记

/**  功能:     排序
  *日期:     2017年9月24日
  *作者:     yzh
  *开发环境:  QT
  **/

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

#define MAX_STACK_LENGTH 100     //非递归快速排序调用栈
#define MAX_LENGTH 20            //数组最大值

//对于数值型 keyType
#define EQ(a,b) ((a) == (b))     //比较 a == b ?
#define LT(a,b) ((a) < (b))      //比较 a < b ?
#define LQ(a,b) ((a) <= (b))     //比较 a <= b ?

typedef int KeyType;             //查找关键字类型
typedef char InfoType;           //其他信息

typedef struct {                 // 信息体
    KeyType key;
    InfoType otherInfo;
}RedType;

typedef struct {                //数组结构
    RedType r[MAX_LENGTH+1];    //r[0]闲置或用作哨兵;
    int length;
}SqList;

typedef struct {                //栈节点
    int l,h;

}StackNode;

typedef struct {                //栈
    StackNode node[MAX_STACK_LENGTH];
    int idx;
}Stack;

//插入模拟数据
int insertSQ(SqList *list){

    for(int i = 1;i<MAX_LENGTH+1;i++){
        list->r[i].key = rand()%1000;
        list->r[i].otherInfo = 96+i;
    }
    list->length = MAX_LENGTH+1;
}

//打印数组
int printf_SQ(SqList *list){
    for(int i = 1 ; i<list->length ; i++){
        if(i<list->length-1){
            printf("%d,",list->r[i]);
        }else{
            printf("%d\n",list->r[i]);
        }

    }
}

//插入排序
int sort_I(SqList *list){
    int i,j;
    for(i = 2;i<list->length;++i){
        if(LT(list->r[i].key,list->r[i-1].key)){
            list->r[0] = list->r[i];
            list->r[i] = list->r[i-1];
            for(j = i-2;LT(list->r[0].key,list->r[j].key); --j){
                list->r[j+1] = list->r[j];
            }
            list->r[j+1] = list->r[0];
        }

    }
}

//插入排序改进:折半插入排序
int sort_B_I(SqList *l){
    int i , j;
    int low , high,mid;
    for(i = 2; i<l->length;i++){
        if(LT(l->r[i].key,l->r[i-1].key)){
            l->r[0] = l->r[i];
            l->r[i] = l->r[i-1];
            low = 1;high = i-2;
            while(low<=high){
                mid = (low+high)/2;
                if(LT(l->r[0].key,l->r[mid].key)){
                    high = mid -1;
                }else{
                    low = mid+1;
                }
            }
            for(j = i-2; j>high;j--){
                l->r[j+1] = l->r[j];
            }
            l->r[high+1] = l->r[0];
        }
    }
}

//冒泡排序
int sort_B(SqList *list){
    int i,j;
    for(i = 1;i<list->length;i++){
        for(j = i+1;j<list->length ; j++){
            if(LT(list->r[j].key,list->r[i].key)){
                list->r[0] = list->r[j];
                list->r[j] = list->r[i];
                list->r[i] = list->r[0];
            }
        }
    }
}

//选择排序
int sort_S(SqList *list){
    int i,j;

    for(i = 1 ; i<list->length ;i++){
        list->r[0] = list->r[i];
        int min = i;
        for(j = i+1; j<list->length ; j++){
            if(LT(list->r[j].key,list->r[0].key)){
                list->r[0] = list->r[j];
                min = j;
            }
        }
        list->r[min] = list->r[i];
        list->r[i] = list->r[0];

    }
}

//快速排序
int Partition(SqList *L,int l ,int h){
    L->r[0] = L->r[l];

    while(LT(l,h)){
        while(LT(l,h)&&LT(L->r[0].key,L->r[h].key)){--h;}
        L->r[l] = L->r[h];
        while(LT(l,h)&&LQ(L->r[l].key,L->r[0].key)){++l;}
        L->r[h] = L->r[l];
    }
    L->r[l] = L->r[0];
    return l;
}

//递归算法
void QSort(SqList *L, int low, int high) {  //算法10.7
  // 对顺序表L中的子序列L.r[low..high]进行快速排序
  int pivotloc;
  if (low < high) {                      // 长度大于1
    pivotloc = Partition(L, low, high);  // 将L.r[low..high]一分为二
    QSort(L, low, pivotloc-1);           // 对低子表递归排序,pivotloc是枢轴位置
    QSort(L, pivotloc+1, high);          // 对高子表递归排序
  }
} // QSort

StackNode pop(Stack *stack){

    StackNode node = stack->node[stack->idx];
    stack->idx--;
    return node;
}

void push(Stack *stack , int l,int h){
    stack->idx++;
    stack->node[stack->idx].h = h;
    stack->node[stack->idx].l = l;
}

//非递归算法
void sort_Q(SqList *L,int low,int high){
    int pivotloc;
    Stack stack;
    push(&stack,low,high);
    StackNode node;
    while(stack.idx>0){
        node = pop(&stack);
        if(node.l <node.h){
            pivotloc = Partition(L, node.l, node.h);
            push(&stack,pivotloc+1,node.h);
            push(&stack,node.l,pivotloc-1);
        }
    }
}

void QuickSort(SqList *L) {          // 算法10.8
   // 对顺序表L进行快速排序
   //sort_Q(L, 1, L->length-1);    //调用非递归快速排序
   //QSort(L, 1, L->length-1);        //调用递归快速排序
} // QuickSort

int main(int argc, char *argv[])
{
//    测试栈
//    Stack stack;
//    push(&stack , 1,2);
//    push(&stack , 2,3);
//    push(&stack , 4,6);
//    StackNode node= pop(&stack);
//    printf("%d,%d\n",node.l,node.h);
//    StackNode node2= pop(&stack);
//    printf("%d,%d\n",node2.l,node2.h);
//    StackNode node3= pop(&stack);
//    printf("%d,%d\n",node3.l,node3.h);
//    return 0;

    SqList list;

    insertSQ(&list);    //插入模拟数据
    printf_SQ(&list);   //打印测试数据
    //(41,467,334,500,169,724,478,358,962,464,705,145,281,827,961,491,995,942,827,436)
    printf("-------------------------------------------\n");
//    sort_B(&list);    //冒泡排序
//    sort_I(&list);    //插入排序
//    sort_S(&list);    //选择排序
//    sort_B_I(&list);  //插入排序改进:折中插入排序
    QuickSort(&list);   //快速排序

    printf_SQ(&list);   //打印排序后数组
    //(41,145,169,281,334,358,436,464,467,478,491,500,705,724,827,827,942,961,962,995)
    printf("-------------------------------------------\n");

    return 0;
}
时间: 2024-08-20 21:26:40

C语言 排序算法 - 数据结构学习笔记的相关文章

数据结构与算法基础学习笔记

*********************************************            ---算法与数据机结构--- 数据结构:由于计算机技术的发展,需要处理的对象不再是纯粹的数值,还有像字符,表,图像等具有一定结构的数据,需要用好的算法来处理这些数据. 我们把现实中大量而又复杂的问题以特定的数据类型的特定的存储结构保存到主存储器中,以及在此基础上为实现某个功能而执行的相应操作(查找排序),这个相应的操作也叫算法. 数据结构 = 个体 +个体的关系算法 =对存储数据的操

数据结构学习笔记(1)-数据结构与算法

基本概念和术语 1.数据  数据元素  数据对象   数据结构 数据:在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称. 数据元素:是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理. 数据对象:是性质相同的数据元素的集合.是数据的一个子集. 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合. 2.数据结构 数据结构分为逻辑结构和物理结构 2.1逻辑结构 逻辑结构表示数据之间的相互关系.通常有四种基本结构: 集合:结构中的数据元素除了同属于一种类型外,别

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

数据结构学习笔记之栈

栈(stack)  是限定仅在表尾进行插入或删除操作的线性表.因此,对栈来说,表尾端有其特殊含义,称为栈项(top),相应地,表头端称为栈底(bottom).不含元素的空表称为空栈. 栈有两种存储表示方法:顺序栈和链栈.顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置.通常的习惯做法是以top=0表示空栈,鉴于C语言中数组的下标约定从0开始,则当以C作描述语言时,如此设定会带来很大不便:另一方面,由于栈在使用过程

小猪的数据结构学习笔记(五)

小猪的数据结构学习笔记(五) 线性表之--循环链表                           --转载请注明出处:coder-pig 循环链表知识点归纳: 相关代码实现: ①判断是否为空表: ②单循环链表的存储结构 其实和单链表的结构是一样的! /*定义循环链表的存储结构*/ typedef struct Cir_List { int data; struct Cir_List *next; }Lnode; ③初始化循环单链表 代码如下: //1.循环链表的初始化 //表示一个元素,如

【数据结构学习笔记(C#描述)】(二)算法分析

由上一章的内容可知软件质量的重要特征之一就是能够高效的利用资源(运行效率),因此我们就要考虑如何创建出能够高效利用CPU及内存的数据结构与算法.而算法分析的目的就是为了让我们能够认识到算法对于资源的利用效率. 我们要想分析算法的效率,就需要找到一个评价算法效率的标准及方法. 一般我们如果能快速的利用CPU就会更好的节省时间,因此在时间层面上我们的评价标准就是时间复杂度,而如果我们能够较好的利用内存的话我们将会节省更多的内存空间,因此在空间层面上我们的评价标准就是空间复杂度. 所谓时间复杂度和空间

数据结构学习笔记——线性表的应用

数据结构学习笔记——线性表的应用 线性表的应用 线性表的自然连接 计算任意两个表的简单自然连接过程讨论线性表的应用.假设有两个表A和B,分别是m1行.n1列和m2行.n2列,它们简单自然连接结果C=A*B(i==j),其中i表示表A中列号,j表示表B中的列号,C为A和B的笛卡儿积中满足指定连接条件的所有记录组,该连接条件为表A的第i列与表B的第j列相等. 如:         1 2 3                3 5 A  =  2 3 3         B =  1 6       

数据结构学习笔记——绪论

数据结构学习笔记——绪论 为了更贴切的描述一种数据结构,通常采用二元组表示:(对于一种数据结构其逻辑结构唯一) B=(D,R)其中,B是一种数据结构,它由数据元素的集合D和D上二元关系的集合R所组成.即D={ di | 1 <= i<= n, n > 0}R={ rj | 1 <= j<= n, n > 0}D 上的一个关系r是序偶的集合,对于r中任一序偶<x,y>(x,y属于集合D),把x叫做偶序第一节点,把y叫做偶序第二结点,又称序偶的第 一结点为第二结

小猪的数据结构学习笔记(三)

小猪的数据结构学习笔记(三) 线性表之单链表 本章引言: 上一节中我们见识了第一个数据结构--线性表中的顺序表; 当你把操作的代码自己写几遍就会有点感觉了,如果现在让你写顺序表的 插入算法,你能够想出大概的代码么?如果可以,那么你就可以进入新的章节了; 否则,还是回头看看吧!在本节,我们将迎来线性表的链式表示--单链表 单链表和顺序表有什么优势和劣势呢?单链表的头插法和尾插法有什么不同呢? 请大家跟随笔者的脚步来解析线性表中的单链表把! 本节学习路线图 路线图解析: ①先要理解顺序表和单链表各自