基于partation的数据处理

       在求数据的前K小项或者找找中位数以及快速排序算法中都会用到partation找数据的合适位置,

从而减小时间效率,本小章节总结常见的处理算法。

一:求数组的第K大的数

第一种解法:基于partation的时间复杂度为o[n]的解法!

这里是一个收敛数列:1 + 1/2 +1/3 + .... = 2

#include<iostream>
using namespace std;


int swap(int a[],int i,int j)
{
    int tmp = a[i];
     a[j] = a[i] ;
     a[i] = a[j] ;
}
int Partition(int a[], int i, int j)
{
    int  temp = a[i];
        while (i < j)
        {
            //从后往前扫找比枢轴值小的交换位置
            while (i<j&& a[j] >= temp) 
            {j--;}
            swap(a,i,j);
            while (i<j&& a[i] <= temp)
            {i++;}
            swap(a,i,j);
        }
        return i;
}
void Qsort(int *a,int low ,int high)
{
    int mykey ;
    if(low < high)
    {
        mykey = Partition(a,low,high);
        Qsort(a,low,mykey-1);
        Qsort(a,mykey+1, high);
    }
}

//o[n]时间的算法,缺点会改变原数据
int Find(int a[],int n,int k)

{

        int left=0;
        int right=n-1;
        int index=Partition(a,left,right);
        while(index!=k)
        {
            if(index>k)
              {
                        right=index-1;
                        index=Partition(a,left,right);
                        }
                else
                {

                        left=index+1;
                        index=Partition(a,left,right);
                }

        }

       return a[k-1];
}

int main()
{
    int a[ ] = { 1,2,3,6,6,7,9,8};
    Qsort(a,0,7);
    for(int i=0;i<8;++i)
    {
        cout << a[i] ;
    }
    cout << endl;
    cout << Find(a,8,6);
 
}

可以看到的是这里找到的是从小到大的第6个

第二种解法:相对更为合理,特别适合做大数据的处理,以空间换取时间的做法。

利用了最大堆处理


class Solution {
public:
    vector<int> GetLeastNumbers_Solution(vector<int> input, int k) {
        int len=input.size();
        vector<int> res;
        if(len<=0||k>len||k<=0) return res;
        for(int i=0;i<k;++i)
        {
            res.push_back(input[i]);
        }
        //vector<int> res(input.begin(),input.begin()+k);
        //建堆
        make_heap(res.begin(),res.end());
         
        for(int i=k;i<len;i++)
        {
            if(input[i]<res[0])
            {
                //先pop,然后在容器中删除
                pop_heap(res.begin(),res.end());
                res.pop_back();
                //先在容器中加入,再push
                res.push_back(input[i]);
                push_heap(res.begin(),res.end());
            }
        }
        //使其从小到大输出
        sort_heap(res.begin(),res.end());
         
        return res;
         
    }
};

数组中超过一半的数

这里是用 map实现了 hash计数

习惯了 map对象 insert的方式插入对上面的额插入方式比较不适用,但是这是完全可以的

可以对它稍加变形

基于partation的单向链表的快速排序算法!

//#include <iostream>
#include "stdio.h"
#include "stdlib.h"
//using namespace std;
//构造结点并初始化
typedef struct node 
{
    int val;
    node * next;
    node(int x):val(x),next(NULL){}
}mynode,*pmynode;

void swap(int* a,int * b)
{
   int tmp  = *a; 
   * a  = *b;
   * b = tmp ;
}
//定位
node *partion(node *pbegin ,node * pend)
{
    if(pbegin ==pend ||pbegin->next ==pend)
    
           return pbegin;
    int mykey = pbegin ->val; //选择基准
    node * p =pbegin ; 
    node* q =pbegin;
    while(q != pend)
    {
        if(q->val< mykey )
        {
            p = p->next;
            //这两种交换写法都是正确的
            //swap( &(p->val) ,&(q ->val)); //小于则交换
              swap( &p->val ,&q ->val); //小于则交换
        }
        q =q ->next;//否则一直往下走
    }
    swap(&p->val,&pbegin->val); //定位
    return p;
}
void quick_sort(node *pbegin,node *pend)
{
    if(pbegin ==pend ||pbegin->next ==pend)
    
        return ;
    node *mid =partion(pbegin,pend);
    quick_sort(pbegin,mid);
    quick_sort(mid->next,pend);
}

node *mysort(node *head,node *end)
{    //如果头结点为空,则直接跳出循环
    //if(head ==NULL ||head -> next==NULL);
       //return head;
    quick_sort(head ,end);
    return head;
}

int main()
 {
    node a(1);
    node b(4);
    node c(6);
    node d(2);
    node e(5);
    node f(7);
    a.next = &b;
    b.next = &c;
    c.next = &d;
    d.next = &e;
    e.next = &f;

    //swap( & b->val ,& c->val);
    pmynode head = & a;
    printf("%d\n", head->val);
    printf("%d\n", (&a)->val);
    //printf("%d", &a->val);
   //如果节点的指针不为空则打印节点
    while(head)
    {
        printf("%d \t",head ->val);
        head =head -> next;
       
    }
    printf("\n");
   // pmynode head0 =mysort(head,&f);
    pmynode head0 =mysort(&a,&f);
    while(head0)
    {
        printf("%d \t",head0 ->val);
        head0 =head0 -> next;
    }
    
    return 0;
 }
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值