数据结构 排序

Posted 上山打老虎D

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 排序相关的知识,希望对你有一定的参考价值。

1. DS排序–希尔排序

题目描述

给出一个数据序列,使用希尔排序算法进行降序排序。

间隔gap使用序列长度循环除2直到1

输入

第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据(n>1)
第三行输入n个数据,都是正整数,数据之间用空格隔开
以此类推

输出

对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。

输入样例

2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222

输出样例

444 333 55 111 22 6
444 333 111 55 22 6

444 555 666 2222 77 77 33 1
666 2222 444 555 77 77 33 1
2222 666 555 444 77 77 33 1

参考代码

#include<iostream>

using namespace std;
const int increment = 2;
void shellSort(int a[], int len)
{
    int temp = 0;
    unsigned gap = len / increment; // 步长初始化
    while (gap) // while gap>=1
    {
        for (unsigned i = gap; i < len; ++i) // 分组,在每个子序列中进行插入排序
        {
            temp = a[i];//将当前的元素值先存起来方便后面插入
            unsigned j = i;
            while (j >= gap && temp > a[j - gap])//寻找插入位置
            {
                a[j] = a[j-gap];
                j -= gap;
            }
            a[j] = temp;
        }
        for (int i = 0;i < len;i++)
        {
            if (i != 0)cout << " " << a[i];
            else cout << a[i];
        }
        cout << endl;
        gap = gap / increment;
    }
}
int main()
{
    int t;
    int n;
    int* data;
    cin >> t;
    while (t--)
    {
        cin >> n;
        data = new int[n];
        for (int i = 0;i < n;i++)
            cin >> data[i];
        shellSort(data, n);
        cout << endl;
    }
    return 0;
}

2. DS排序–快速排序

题目描述

给出一个数据序列,使用快速排序算法进行从小到大的排序

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入

第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据
第三行输入n个数据,都是正整数,数据之间用空格隔开
以此类推

输出

每组测试数据,输出每趟快排的结果,即每次排好一个数字结果(长度为1的子序列,不用排,不用输出)。不同测试数据间用空行分隔。

输入样例

2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222

输出样例

55 22 6 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444

1 33 77 555 444 77 666 2222
1 33 77 555 444 77 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222

参考代码

#include <iostream>
using namespace std;
void Quick_sort(int nums[],int start,int end,int n)
{
    int temp;
    if(end>start)            //前面不断根据数据交换,一直交换到中间,最后枢纽元取中间的数的下标i
    {
        int i=start,j=end,flag=0;
        while(i<j)
        {
            if(nums[i]>nums[j])
            {
                temp=nums[i];
                nums[i]=nums[j];
                nums[j]=temp;
                if(flag==0)
                {
                    i++;
                    flag=1;
                }
                else
                {
                    j--;
                    flag=0;
                }
            }
            else
            {
                if(flag==0)
                {
                    j--;
                }
                else
                {
                    i++;
                }
            }
        }
        for(int k=0;k<n;k++)        //输出数组
        {
            cout<<nums[k];
            if(k!=n-1)
                cout<<' ';
        }
        cout<<endl;
        Quick_sort(nums,start,i-1,n);
        Quick_sort(nums,i+1,end,n);
    }
}
int main()
{
    int t,n;
    cin>>t;
    int nums[100];
    while(t--)
    {
        cin>>n;
        for(int i=0;i<n;i++)
            cin>>nums[i];
        Quick_sort(nums,0,n-1,n);
        cout<<endl;
    }
}

3. DS内排—直插排序

题目描述

给定一组数据,使用直插排序完成数据的升序排序。

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入

数据个数n,n个数据

输出

直插排序的每一趟排序结果

输入样例

7 34 23 677 2 1 453 3

输出样例

23 34 677 2 1 453 3
23 34 677 2 1 453 3
2 23 34 677 1 453 3
1 2 23 34 677 453 3
1 2 23 34 453 677 3
1 2 3 23 34 453 677

参考代码

#include<iostream>
using namespace std;

void DirectSort(int data[], int n)
{
	int temp;
	for (int i = 1;i < n;i++)
	{
		if (data[i] < data[i - 1])
		{
			temp = data[i];
			data[i] = data[i - 1];
			int j;
			for (j = i - 1;temp < data[j];--j)
			{
				data[j + 1] = data[j];
			}
			data[j + 1] = temp;
		}
		for (int k = 0;k < n;k++)
		{
			cout << data[k];
			if (k != n - 1)cout << ' ';
		}
		cout << endl;
	}
}

int main()
{
	int n;
	int* data;
	cin >> n;
	data = new int[n];
	for (int i = 0;i < n;i++)
		cin >> data[i];
	DirectSort(data, n);
	return 0;
}

4. DS内排—2-路归并排序

题目描述

输入一组字符串,用2-路归并排序按字典顺序进行降序排序。

输入

测试次数t

每组测试数据:数据个数n,后跟n个字符串,字符串不含空格。

输出

对每组测试数据,输出2-路归并排序的每一趟排序结果。每组测试数据的输出之间有1空行。

输入样例

2
6 shenzhen beijing guangzhou futian nanshan baoan
10 apple pear peach grape cherry dew fig haw lemon marc

输出样例

shenzhen beijing guangzhou futian nanshan baoan
shenzhen guangzhou futian beijing nanshan baoan
shenzhen nanshan guangzhou futian beijing baoan

pear apple peach grape dew cherry haw fig marc lemon
pear peach grape apple haw fig dew cherry marc lemon
pear peach haw grape fig dew cherry apple marc lemon
pear peach marc lemon haw grape fig dew cherry apple

参考代码

#include<iostream>
#include<cstring>
using namespace std;
int n;
void copy(string* &str, string* &st){ //实时更换str字符串中的内容
     for(int i= 1; i<= n; i++)
       str[i]= st[i];
}
void Merge(string* &str, string* &st, int m, int nn, int gap){//合并两个区间
    int k;
    int i, j;
    for(i= m,j= nn, k= m; i< m+ gap&&j< nn+ gap&&j<= n; k++){
        if(str[i]> str[j])
          st[k]= str[i++];
        else
           st[k]= str[j++]; 
         
    }
    while(i< m+ gap) 
      st[k++]= str[i++];
    while(j< nn+ gap&&j<= n)
      st[k++]= str[j++];
    copy(str, st);
}
void print(string* &st){//输出
        for(int i= 1; i<= n; i++){
            cout<<st[i];
            if(i!= n)
              cout<<' ';
            else
              cout<<endl;
        }   
}
void Msort(string* &str, string* &st){//归并排序
     
    int gap= 1;//每个区间的长度
    int num= n;//区间的个数
    int i;//要合并的第一个区间开头
    int j;//要合并的第二个区间的开头
    while(num> 1){//在组数小于1时退出循环
        i= 1;
        j= gap+ 1;
      
        while(j<= n){
 
            Merge(str, st, i, j, gap);
            num--;
            i+= gap* 2;//每次跳两个组的间距
            j+= gap* 2;     
        }
        gap= gap* 2;
        print(st);
    }
     
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        string* str= new string[n+ 5];
        string* st= new string[n+ 5];
        for(int i= 1; i<= n; i++){
            cin>>str[i];
            st[i]= str[i];
        }
            
        Msort(str, st);
        cout<<endl;
        delete []str;
        delete []st;
    }
    return 0;
}

5. DS内排—堆排序

题目描述

给定一组数据,使用堆排序完成数据的降序排序。(建小顶堆)。

输入

数据个数n,n个整数数据

输出

初始创建的小顶堆序列

每趟交换、筛选后的数据序列,输出格式见样例

输入样例

8 34 23 677 2 1 453 3 7

输出样例

8 1 2 3 7 23 453 677 34
8 2 7 3 34 23 453 677 1
8 3 7 453 34 23 677 2 1
8 7 23 453 34 677 3 2 1
8 23 34 453 677 7 3 2 1
8 34 677 453 23 7 3 2 1
8 453 677 34 23 7 3 2 1
8 677 453 34 23 7 3 2 1

参考代码

#include <iostream>
using namespace std;

class heapSort{
    int *array;
    int len;
public:
    heapSort(int n);
    ~heapSort();
    void Sift(int pos,int length);
    void Sort();
    void outPut();
};

heapSort::heapSort(int n) {
    len=n;
    array = new int[n];
    for(int i=0;i<n;i++)
        cin>>array[i];

    for(int i=n/2;i>=0;i--)
        Sift(i,len);
    //输出堆初始化
    outPut();
}

heapSort::~heapSort() {
    delete []array;
}

void heapSort::Sift(int pos, int length) {
    int lChild=2*pos+1,rChild=2*pos+2;
    if(lChild<length)    //左孩子不超过最大值
    {
        if(rChild<length)  //存在右孩子
        {
            if(array[lChild]<array[rChild])
            {
                if(array[lChild]<array[pos])
                {
                    int temp=array[pos];
                    array[pos]=array[lChild];
                    array[lChild]=temp;
                    Sift(lChild,length);   //和左孩子交换之后,筛选左孩子
                }
            }
            else{
                if(array[rChild]<array[pos])
                {
                    int temp=array[pos];
                    array[pos]=array[rChild];
                    array[rChild]=temp;
                    Sift(rChild,length);   //和右孩子交换之后,筛选右孩子
                }
            }
        }
        else    //只有左孩子,没右孩子
        {
            if(array[lChild]<array[pos])
            {
                int temp=array[pos];
                array[pos]=array[lChild];
                array[lChild]=temp;
                Sift(lChild,length);   //和左孩子交换之后,筛选左孩子
            }
        }
    }
}

void heapSort::Sort() {
    for(int i=len-1;i>0;i--)    //从最后一个结点开始筛选,每次减一
    {
        int temp=array[i];
        array[i]=array[0];
        array[0]=temp;
        Sift(0,i);
        outPut();
    }

}

void heapSort::outPut() {
    cout<<len<<' ';
    for(int i=0;i<len;i++) {
        cout << array[i];
        if(i!=len-1)
            cout<<' ';
    }
    cout<<endl;
}

int main()
{
    int n;
    cin>>n;
    heapSort myHeap(n);
    myHeap.Sort();
    return 0;
}

以上是关于数据结构 排序的主要内容,如果未能解决你的问题,请参考以下文章

以下代码片段的时间复杂度是多少?

ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段

排序02-直接插入排序法

markdown 数组排序片段

Java排序算法 - 堆排序的代码

Realm和RecyclerView项目排序和自动ViewPager片段通信