zoukankan      html  css  js  c++  java
  • 数据结构之查找与排序

    查找 

     静态查找:查找时,只查找读取 

      顺序表上查找 

            无序表上查找,设置位置0为岗哨,从后往前查找,查找长度为(n+1)/2

            有序表上查找,使用二分查找,平均查找长度为 log2(n+1)-1

      索引顺序表上查找,索引表将顺序表分别分割为若干块,顺序表按块有序,查找长度为 (n/s+s)/2+1

     动态查找 

      二叉排序树:或为空树或具有下列性质:

           1.若左子树不为空,则左子树上的所有结点的键值均小于它的根结点的键值,

           2.若右子树不为空,则右子树上的所有结点的键值均小于它的根结点的键值,

           3.根的左子树,右子树均为二叉排序树

      中序遍历即可得到升序序列

      查找长度与树的形态有关,介于O(n)和log2(n)之间

      散列表:使数据的存储位置与键值之间建立某件联系,减少比较次数

           散列函数:数据元素的键值和存储位置之间建立的对应关系H

           散列表,散列地址,      

           冲突 k1!=k2 H(k1)=H(k2),则称k1,k2是相对H的同义词

           堆积:非同义词之间对同一散列地址的争夺现象 

           常用散列法:数字分析法,保留余数法,平方取中发,基数转换法

           解决冲突的方法:线性探测法 (地址+1) ,二次探测法(+-k2),链地址法,多重散列法,公共溢出区法 

    排序:内部排序,外部排序 

             内部排序:插入排序,交换排序,选择排序,归并排序 

                       插入排序:直接插入排序 O(n2),折半插入排序,表插入排序,希尔排序 nlog2n n^s 

                                直接插入排序:依次将每个记录插入到一个已排好序的有序表中去,得到一个新的,记录数增加1的有序表

                                void straightInertSort(List R,int n)

                                {

                                         int i,j;

                                         for(i=2;i<n;i++)

                                         {

                                                   R[0]=R[i];

                                                   j=i-1;

                                                   while(R[0]<R[j])

                                                   {

                                                            R[j+1]=R[j];

                                                            j--;

                                                   }

                                                   R[j+1]=R[0];

                                         }

                                } 

                                希尔排序:以n/2为步长分割List,排序分割的List,再以原步长/2,重复执行,知道步长为0 结束排序。 

                       交换排序:冒泡排序O(n2) ,快速排序 (不稳定,nlog2n  n2) 

                                冒泡排序:是一种交换排序方法,首先将第一个记录和第二个记录比较,若为逆序,则将两个记录交换,然后比较第二个和第三个,依次类推,直到完成第n-1和第n个比较交换位置。此为第一趟起泡。结果使键值最大的记录移动到第n个位置上。然后对前n-1个记录进行同样的操作。

                                void BubbleSort(List R,int n)

                                {

                                         int i,j,temp,endSort;

                                         for(i=1;i<=n-1;i++)

                                         {

                                                   endSort=0;

                                                   for(j=1;j<=n-1-i;j++)

                                                   {

                                                            if(R[j].key>R[j+1].key)

                                                            {

                                                                     temp=R[j];

                                                                     R[j]=R[j+1];

                                                                     R[j+1]=temp;

                                                                     endSort=1;

                                                            }

                                                   }

                                                   if(endSort==0)break;

                                         }

                                }

                                快速排序:

                                void QuickSort(List R,int low,int high)

                                {

                                         if(low<high)

                                         {

                                                   temp=QuickPartition(R,low,high);

                                                   QuickSort(R,low,temp-1);

                                                   QuickSort(R,temp+1,high);

                                         }

                                } 

                                int QuickPartition(List R,int low,int high)

                                {

                                         x=R[low];

                                         while(low<high)

                                         {

                                                   while(low<high&&R[high].key>x.key)

                                                   {

                                                            high--;

                                                   }

                                                   R[low]=R[high];

                                                   while(low<high&&R[low].key<x.key)

                                                   {       

                                                            low++;

                                                   }

                                                   R[high]=R[low];

                                         }

                                         R[low]=x;

                                         return low;

                                } 

                       选择排序:直接选择排序(不稳定 O(n^2)),堆排序(不稳定 nlog2n) 

                                直接选择排序:在第i次选择操作中,通过第n-i次键值比较,从n-i+1个记录中,选出最小的键值记录,并和第i个记录交换。

                                void SelectSort(List R,int n)

                                {

                                         int min,i,j

                                         for(i=1;i<=n-1;i++)

                                         {

                                                   min=i;

                                                   for(j=i+1;j<=n;j++)

                                                   {

                                                            if(R[j].key<R[min].key) min=j;

                                                            if(min!=i) swap(R[min],R[i]);

                                                   }

                                         }

                                } 

                                堆排序:最小堆是一颗以k1为根的完全二叉树,任一结点都不大于它的两个孩子的值。

                                void HeapStort(List R,int n)

                                {

                                         int i;

                                         for(i=n/2;i>=1;i++)

                                                   Shit(R,i,n);

                                         for(i=n;i>=2;i--)

                                         {

                                                  Swap(R[1],R[i]);

                                                   Shit(R,1,i-1);

                                         }

                                } 

            List为完全二叉树 顺序结构存储

            K为 根结点序号

            m为 顺序存储结构最后一个结点位置

                                void Shit(List R,int k,int m)

                                {

                                         int i,j,x;

                                         List t;

                                         i=k;j=i*2;

                                         x=R[k].key;

                                         t=R[k];

                                         while(j<=m)

                                         {

                                                   if(j<m)&&R[j].key>R[j+1].key)

                                                   {

                                                            j++;

                                                   }

                                                   if(x<R[j].key) break;

                                                   else

                                                   {

                                                            R[i]=R[j];

                                                            i=j;

                                                            j=2*i;

                                                   }

                                         }

                                } 

                       归并排序:有序序列的归并(不稳定的 nlog2n),二路归并排序(稳定的 nlog2n)

                                要求待排序序列是有若干有序子序列组成 

                                有序序列的归并: a h m n

                                二路归并排序:有n个有序的子序列,每个序列的长度为1,首先将相邻的两个记录合并,得到较大的n/2个较大的有序子序列,再将相邻的子序列两两合并,得到[[n/2]/2]个有序的子序列,如此反复,直到得到一个长度为n的有序序列位置。 

             排序算法中,没有那种是最优的,就时间复杂度而言,比较简单的排序算法,直接插入,直接选择,冒泡排序等,所需时间复杂度为O(n^2).但是在某些情况下,如初始序列已基本有序,直接插入算法和冒泡算法时间复杂度为O(n)。就待排序列的记录数量而言,当记录数较小时,尽量选择简单的排序算法,当n比较大时并且记录无规律可言时,采用快速排序,堆排序,归并排序等时间复杂度较低的算法。快速排序,直接选择排序,堆排序是不稳定的算法。

  • 相关阅读:
    如何高效处理bug?
    如何获取字符串函数的实现?
    数据处理-csv,pandas
    CentOS 下安装SAC(Seismic Analysis Code)
    CentOS安装使用ffmpeg
    Tensorflow问题记录 --pydot Failed to import pydot. You must install pydot and graphviz for pydotprint to work
    Tensorflow学习记录 --TensorFlow高效读取数据tfrecord
    Committee to boost development of Chinese language teachers
    Consensus-based decentralized auctions for robust task allocation
    Chinese market critical to US firms: US-China Business Council
  • 原文地址:https://www.cnblogs.com/CoreXin/p/5341330.html
Copyright © 2011-2022 走看看