排序1

来源:互联网 发布:现代网络小说家排行榜 编辑:程序博客网 时间:2024/05/20 23:56

 [] 表示一个块
{} 表示注释

kernel_code  kernel_code只考虑最一般的、最基本的情况,不作输入等检查,它不应该给外界直接调用。

//插入排序
{逻辑结构:线性表}
算法思想:
1。从第二个元素开始,依次取出各个数据元素。
2。取出的数据元素跟已经有序的序列作比较,从右往左,至到所有数据比较完毕,或找到一个比取出元素要小的元素为止,设这个元素的位序为i。
3。把取出的数据元素插入到i+1处。

//算法描述
InsertSort( LinearListA )
 for i=2 to Length(LinearListA) do
 [
  x = GetElement(LinearListA, i);
  j = i-1;
  while j>0 and GetElement(LinearListA,j)>x
  [
   SetElement(LinearListA,j+1, GetElement(LinearListA,j)); // 元素后移
   j--;
  ]
  SetElement(LinearListA,j+1);
 ]
{InsertSort end}

//算法时间复杂度(最坏)
O(n^2)

 

// 代码实现
/// 存储结构:顺序表--基本数组
// kernel_code
template< typename T >
void InsertSort(
       T LinearList[],
       const int nListLen
       )
{
 int  nTotalPos = 0;
 for ( nTotalPos = 1; nTotalPos < nListLen; nTotalPos ++ )
 {
  T  element = LinearList[nTotalPos];
  int  nSortedPos = nTotalPos - 1;
  while ( nSortedPos >= 0 && LinearList[nSortedPos] > element )
  {
   LinearList[nSortedPos+1] = LinearList[nSortedPos];
   nSortedPos --;
  }

  LinearList[nSortedPos+1] = element;
 }
}

*******************************

//合并两个已经排好序的线性表
{逻辑结构:线性表}
{存储结构:顺序表}
算法思想:
1。初始化。产生一个线性表LinearListC,表长预定为Length(LinearListA)+Length(LinearListB)。
2。i=1, j=1, k=1分别代表LinearListA、LinearListB和LinearListC的位序。
3。同时从LinearListA和LinearListB中取出两个数据元素x和y并作比较,如果x<=y,则把x插入到LinearlistC并
i=i+1,k=k+1,否则把y插入到LinearListC并j=j+1,k=k+1。
4。如果LinearListA已经全部取完,则把LinearListB中剩下的数据无素依序插入到LinearListC中,否则把
LinearListB中剩下的元素依序插入到LinearListC中。

//算法描述
Merge( L[], R[] )
 n1 = Length(L);
 n2 = Length(R);
 // create new LinearList and initial
 A = CreateList[1..(n1+n2)];
 i = 1;
 j = 1;
 k = 1;
 while i<=n1 and j<=n2
 [
  x = L[i];
  y = R[j];
  if x <= y
  [
   A[k] = x;
   i = i + 1;
   k = k + 1;
  ]
  else
  [
   A[k] = y;
   j = j + 1;
   k = k + 1; 
  ]
 ]
 while i<=n1
 [
  A[k] = L[i]
  i = i + 1;
  k = k + 1;
 ]
 while j<n2
 [
  A[k] = R[j];
  j = j + 1;
  k = k + 1;
 ]
{Merge end}

//算法时间复杂度(最坏)
O(n)

// 代码实现
/// 存储结构:顺序表--基本数组
// kernel_code
template<typename T>
void MergeSortedList(
      const T L[],
      const int nLLen,
      const T R[],
      const int nRLen,
      T A[]  // 输出
      )
{
 int nLPos = 0;
 int nRPos = 0;
 int nAPos = 0;

 while ( nLPos < nLLen && nRPos < nRLen )
 {
  T  leftElement = L[nLPos];
  T  rightElement = R[nRPos];
  if ( leftElement <= rightElement )
  {
   A[nAPos] = leftElement;
   nAPos ++;
   nLPos ++;
  }
  else
  {
   A[nAPos] = rightElement;
   nAPos ++;
   nRPos ++;
  }
 }

 while ( nLPos < nLLen )
 {
  A[nAPos] = L[nLPos];
  nAPos ++;
  nLPos ++;
 }
 while ( nRPos < nRLen )
 {
  A[nAPos] = R[nRPos];
  nAPos ++;
  nRPos ++;
 }
}


//在同一个线性表中合并这个线性表中已经排好序的两个部分的数据
{逻辑结构:线性表}
{存储结构:顺序表}
{数据特点:在同一个线性表}
{算法特点:产生两个新的线性表并在表尾加上无穷大的数,避免最后判断某张表是否已经取完}
算法思想:
1。初始化。假设要合并的两部分数据的个数分别为n1和n2。
产生两个线性表LinearListA和LinearListB,长度分别设为(n1+1)和(n2+1)。
2。把原始线性表LinearListC中要合并的两部分数据分别拷贝到LinearListA和LinearListB。
3。在LinearListA和LinearListB末尾分别加入一个无穷大的数。
4。i=1, j=1, k=p分别代表LinearListA、LinearListB和LinearListC的位序。
5。同时从LinearListA和LinearListB中取出两个数据元素x和y并作比较,如果x<=y,则把x插入到LinearlistC并
i=i+1,k=k+1,否则把y插入到LinearListC并j=j+1,k=k+1。
6。当插入基本操作达到(n1+n2)次时,算法结束。

//算法描述
Merge( srcList, p, q, r ) 
// srcList为原始线性表,p到q为已排序的数据集1,p+1到r为已排序的数据集2
 n1 = q - p + 1;
 n2 = r - q;
 // create two new LinearList and initial
 L = CreateList[1..(n1+1)];
 R = CreateList[1..(n2+1)];
 // copy
 for i=1 to n1
 [
  L[i] = srcList[p+i-1]; 
 ]
 for j=1 to n2
 [
  R[i] = srcList[q+j];
 ]
 // 分别加入一个无穷大的数InfiniteNum
 L[n1+1] = InfiniteNum;
 R[n2+1] = InfiniteNum;

 i = 1;
 j = 1;
 for k=p to r
 [
  x = L[i];
  y = R[j];
  if x <= y
  [
   A[k] = x;
   i = i + 1;
  ]
  else
  [
   A[k] = y;
   j = j + 1;
  ]
 ]
{Merge end}

//算法时间复杂度(最坏)
O(n)

// 代码实现
/// 存储结构:顺序表--基本数组
////// 按照算法描述本来应该给新产生的线性表加入“哨兵值”,但由于不知客户指定的数据类型故
////// 无法加入。没有找到解决方法,暂时使用最后判断表是否取完的方法。
// kernel_code
template< typename T >
void MergeSortedList(
      T  srcList[],
      const int leftPos,
      const int midPos,
      const int rightPos
      )
{
 int nLeftListLen = midPos - leftPos + 1;
 int nRightListLen = rightPos - midPos;
 T * pLeftList = new T[nLeftListLen];
 T * pRightList = new T[nRightListLen];

 for ( int nLeftPos = 0; nLeftPos < nLeftListLen; nLeftPos ++ )
 {
  pLeftList[nLeftPos] = srcList[leftPos + nLeftPos];
 }
 for ( int nRightPos = 0; nRightPos < nRightListLen; nRightPos ++ )
 {
  pRightList[nRightPos] = srcList[ midPos + 1 + nRightPos ];
 }
 
 // how to add the infinite number when not know the type T?  so now cancel this operate

 int nLeftPos = 0;
 int nRightPos = 0;
 int nSrcPos = leftPos;
 while ( nLeftPos < nLeftListLen && nRightPos < nRightListLen )
 {
  T  leftElement = pLeftList[nLeftPos];
  T  rightElement = pRightList[nRightPos];
  if ( leftElement <= rightElement )
  {
   srcList[nSrcPos] = leftElement;
   nSrcPos ++;
   nLeftPos ++;
  }
  else
  {
   srcList[nSrcPos] = rightElement;
   nSrcPos ++;
   nRightPos ++;
  }
 }
 while ( nLeftPos < nLeftListLen )
 {
  srcList[nSrcPos] = pLeftList[nLeftPos];
  nSrcPos ++;
  nLeftPos ++;
 }
 while ( nRightPos < nRightListLen )
 {
  srcList[nSrcPos] = pRightList[nRightPos];
  nSrcPos ++;
  nRightPos ++;
 }

 delete [] pLeftList;
 pLeftList = NULL;
 delete [] pRightList;
 pRightList = NULL;
}

*******************************************

//合并排序
{逻辑结构:线性表}
{存储结构:顺序表}
{使用上面的合并算法,非原地排序,因为Merge不能原地进行}
算法思想:
1。如果线性表的长度大于1,则把线性表从中间划分为LeftList和RightList两部分。
2。对LeftList递归的使用本算法完成自身的排序。
3。对RightList递归的使用本算法完成自身的排序。
4。合并LeftList和RightList。

//算法描述
MergeSort( LinearListA, p, r ) // LinearListA为线性表, p、r分别为要求排序的最小和最大位序
 if p < r
 [
  // 取得中心点
  mid = (p+r)/2;
  // 递归完成自身的排序
  MergeSort(LinearListA, p, mid);
  MergeSort(LinearListA, mid+1, r);
  // 合并,这个算法在前面已经实现
  Merge(LinearListA, p, mid, r);
 ] 
{MergeSort end}

//算法时间复杂度(最坏)
O(nlgn)

// 代码实现
/// 存储结构:顺序表--基本数组
// kernel_code
template< typename T >
void MergeSort(
      T srcList[],
      const int leftPos,
      const int rightPos
      )
{
 if ( leftPos < rightPos )
 {
  int mid = (leftPos + rightPos) / 2;
  MergeSort( srcList, leftPos, mid );
  MergeSort( srcList, mid + 1, rightPos );
  MergeSortedList( srcList, leftPos, mid, rightPos );
 }
}

原创粉丝点击