zoukankan      html  css  js  c++  java
  • 插入排序

    也是在做链表题目时,有一道题是用链表结构进行插入排序,因此,对插入排序的数组结构和链表结构做了一个总结,并分析了它们的复杂度。

    插入排序:将一个记录插入到已经排好序的有序表中,从而得到一个新的,记录数增加1的有序表。

    1、顺序表的插入排序

    关键:有两重循环,第一层循环是遍历所有无序元素,第二层循环是遍历已排好序的部分并进行插入

    顺序表结构:

    1 #define MAXSIZE 100
    2 struct SqList
    3 {
    4     int data[MAXSIZE];
    5     int length;
    6 };

    插入排序代码:

     1 oid insertsort(SqList *p)
     2 {
     3     int i,j;
     4     //数组长度为length,但是遍历只进行length-1次
     5     for (i = 0;i < p->length-1;i++)
     6     {
     7         if (p->data[i] > p->data[i+1])
     8         {
     9             int temp = p->data[i+1];
    10             for (j = i;j>=0&&(p->data[j] > temp);j--)
    11             {
    12                 p->data[j+1] = p->data[j];
    13             }
    14             //for循环结束后j又减去1,所以data从j+1算起
    15             p->data[j+1] = temp;
    16         }
    17     }
    18 }

    2、单链表结构的插入排序

    关键:创建一个新链表,将待排序链表的每一个结点有序的插入到新链表中

    链表结构:

    1 struct SqList2
    2 {
    3     int data;
    4     SqList2 *next;
    5     SqList2(int x):data(x),next(NULL) {};
    6 };

    插入排序代码:

     1 //对不带有头结点的单链表进行插入排序
     2 SqList2* insertsort2(SqList2 *p)
     3 {
     4     SqList2 *sortedHead = new SqList2(INT_MIN);
     5     while(p != NULL)
     6     {
     7         //保存p的位置,p的位置一直在移动,直到将p中所有无序的元素都插入sortedHead有序序列中为止
     8         SqList2 *temp = p->next;
     9         SqList2 *cur = sortedHead;
    10         //因为cur的头结点无用,所以直接从cur的第一个节点起插入,如果cur->next不为NULL并且cur->next->data比p->data小则移动cur位置,否则直接插入
    11         while(cur->next != NULL && cur->next->data < p->data)
    12         {
    13             cur = cur->next;
    14         }
    15         //插入(当比cur->data小,比cur->next->data大时,将结点p插入cur与cur->next中间)
    16         p->next = cur->next;
    17         cur->next = p;
    18         //前面对p做了改动,现在恢复p
    19         p = temp;
    20     }
    21     return sortedHead->next;
    22 }

    链表插排代码补齐:

    创建带有头结点的单链表:

     1 //创建带有头结点的单链表
     2 SqList2* createlinklist(SqList2 *s,int n)
     3 {
     4     SqList2 *p,*r;
     5     int m;
     6     int i;
     7     s = (SqList2*)malloc(sizeof(SqList2));
     8     r = s;
     9     for (i=0;i<n;i++)
    10     {
    11         p = (SqList2*)malloc(sizeof(SqList2));
    12         cin >> m;
    13         p->data = m;
    14         r->next = p;
    15         r = p;
    16     }
    17     r->next = NULL;
    18     return s;
    19 }

    主函数:

     1 void main()
     2 {
     3     SqList2 *s = new SqList2(INT_MIN);
     4     //创建带有头结点的单链表
     5     s = createlinklist(s,5);
     6     //向插入排序函数传入不带头结点的链表
     7     s = insertsort2(s->next);
     8     for (int i = 0;i<5;i++)
     9     {
    10         cout << s->data << " ";
    11         s = s->next;
    12     }
    13     system("pause");    
    14 }

    结果:

    3、复杂度分析:

     顺序表插排复杂度:从空间上来看,它需要一个记录的辅助空间,所有空间复杂度为O(1)。从时间上来看,最好的情况是:排序表本身就是有序的,则只需要比较每一项,没有移动的记录,所以时间复杂度为O(n)。最坏的情况是,待排序表是逆序的,此时需要比较的次数和需要移动的次数都达到最大值,此时的时间复杂度是O(n2)。插排也是一直比较稳定的排序方法。

    单链表插排复杂度:空间复杂度是O(1),时间复杂度是O(n2)。

  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/tracyhan/p/5474340.html
Copyright © 2011-2022 走看看