对数组和链表和结构体直接插入排序算法(详细版)

对数组和链表直接插入插入排序算法

插入排序分为 直接插入排序(本文基本描述),折半插入排序希尔插入排序
算法基本思想
:将无序子序列中的一个或几个记录"插入"到有序子序列
中,从而增加有序子序列的长度。

在这里插入图片描述
例如下面这个例子:首先把9当做一个有序序列,后面都是无序序列,然后逐渐把无序序列的元素插入到有序序列。在这里插入图片描述
因此实际上可以把插入排序分为三个部分:定位 ,挤空,插入
在这里插入图片描述
直接插入排序
排序过程:整个排序过程为n-1趟插入,即先将序列中第
1个记录
看成是一个有序子序列,然后从第2个记录开始,
逐个进行插入
,直至整个序列有序
在这里插入图片描述

//**数组实现方法**
在这里插入代void InsertionSort(int A[], int N)//数组_插序排序法
{
	int j, p;
	int Tmp; //保留比较数的下标对应的值
	for (p = 1; p < N; p++)
	{
		/*定位*/		Tmp = A[p];//保留要比较的
		for (j = p; j > 0 && A[j - 1] > Tmp; j--)//只要比Tmp大就换到后一个位置(/*挤空*/),就,(这种则要多判断j>0)
			/*挤空*/			A[j] = A[j - 1];
		/*插入*/		A[j] = Tmp; //实现交换(  这是最后一个被换上去的元素的位置对应的元素  )
	}
}
//算法分析:T(n)=2+3+4+...+N=(N²+N-1)/2=O(N²)
//S(N)=1

//链表实现方法
 ListNode* insertionSortList(ListNode* head)  //链表_InsertionSort
  {
        if (!head || !head->next) //空链表或只有一个元素的链表不必排序
            return head;
        ListNode* dummyhead = new ListNode;//伪头指针
        dummyhead->next = head;
        ListNode* order_max = head;  //有序序列的最大值,无序数列的前一个
        ListNode* disorder_frist = head->next;   //要插入的值(order_max 的后继)
        while (disorder_frist)
        {
            if (disorder_frist->Element < order_max->Element)
            {
                ListNode* Tmp = dummyhead;//!!temp要等于dummyhead,这样才可以比较第一个元素
                while (Tmp->next->Element < disorder_frist->Element)//!!!这里是temp->next:因为要修改前面的temp的指向
                {
                    Tmp = Tmp->next;//从第一个元素开始后移
                }
                order_max->next = disorder_frist->next; // 先删除
                disorder_frist->next = Tmp->next; //后插
                Tmp->next = disorder_frist;          //序      
                disorder_frist = order_max->next;//最大的有序数后面就是无序数第一个。
            }
            else
            {
                order_max = order_max->next;   //要插入的数比【有序max】更大,直接排在后面,order_max 后移
                disorder_frist = disorder_frist->next;  //准备插入下一个无序数列的数。
            }
        }
        return dummyhead->next;//!!!不能返回head!!因为只要第一个元素不是最小的,我们就要改变head的位置。
        //只有dummyhead->next 不变
   }

全部代码

#include<iostream>
#include<ctime>
using namespace std;
 typedef struct ListNode {
      int Element;
      ListNode *next;
  }ListNode; 
  ListNode* CreateList(int N);
  ListNode* insertionSortList(ListNode* head);
  void InsertionSort(int A[], int N);
  int main()
  {
      unsigned int n;
      while (cout<<"\nPlease inout a number of elements to sort ",cin >> n)
      {
          ListNode* List = CreateList(n);
          cout << "The original list is:" ;
          ListNode* x = List;
          for (ListNode* x = List; x != NULL; x = x->next)
              cout << x->Element << " ";
          cout << endl;
          List=insertionSortList(List);
          cout << "The orderly list is  :";
          for ( ListNode* p = List; p != NULL; p = p->next)
              cout << p->Element << "  ";
      }    
      return 0;
      
 }
 ListNode* CreateList(int N) //创建一个无头结点的全是随机数的链表
 {
     ListNode* head = new ListNode;
     ListNode* p =head;
     srand((int)time(NULL)); //取系统时间,随机数
     for (int i = 0; i < N; i++)
     {
         ListNode* p1 = new ListNode;
         p1->Element = rand() % (1000); //将随机数控制在0-999
         p->next= p1;  //创建结点
         p = p1;        
     }
     p->next = NULL;
     return head->next;
 }
  ListNode* insertionSortList(ListNode* head)  //链表_InsertionSort
  {
        if (!head || !head->next) //空链表或只有一个元素的链表不必排序
            return head;
        ListNode* dummyhead = new ListNode;//伪头指针
        dummyhead->next = head;
        ListNode* order_max = head;  //有序序列的最大值,无序数列的前一个
        ListNode* disorder_frist = head->next;   //要插入的值(order_max 的后继)
        while (disorder_frist)
        {
            if (disorder_frist->Element < order_max->Element)
            {
                ListNode* Tmp = dummyhead;//!!temp要等于dummyhead,这样才可以比较第一个元素
                while (Tmp->next->Element < disorder_frist->Element)//!!!这里是temp->next:因为要修改前面的temp的指向
                {
                    Tmp = Tmp->next;//从第一个元素开始后移
                }
                order_max->next = disorder_frist->next; // 先删除
                disorder_frist->next = Tmp->next; //后插
                Tmp->next = disorder_frist;          //序      
                disorder_frist = order_max->next;//最大的有序数后面就是无序数第一个。
            }
            else
            {
                order_max = order_max->next;   //要插入的数比【有序max】更大,直接排在后面,order_max 后移
                disorder_frist = disorder_frist->next;  //准备插入下一个无序数列的数。
            }
        }
        return dummyhead->next;//!!!不能返回head!!因为只要第一个元素不是最小的,我们就要改变head的位置。
        //只有dummyhead->next 不变
   }
  void InsertionSort(int A[], int N)//数组_插序排序法
  {
      int j, p;
      int Tmp; //保留比较数的下标对应的值
      for (p = 1; p < N; p++)
      {
          /*定位*/		Tmp = A[p];//保留要比较的
          for (j = p; j > 0 && A[j - 1] > Tmp; j--)//只要比Tmp大就换到后一个位置(/*挤空*/)
              /*挤空*/			A[j] = A[j - 1];
          /*插入*/		A[j] = Tmp; //实现交换(  这是最后一个被换上去的元素的位置对应的元素  )
      }
  }



``
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值