今天终于开始写排序代码了,以前都是写算法,现在看来写算法跟写真实的程序真是相差万里,简单的冒泡法都让我折腾了半天,要加油啊。

冒泡法将给定数组排序,并输出第k个最大者。代码如下:

#include<stdio.h>
#define len 10

int maopao(int a[]);
int main()
{
 int s[]={2,0,12,3,5,45,78,51,9,23};
 int m,k;

 
 maopao(s);
 for(m=0;m<10;m++)
 {
  printf("s[m]=%d\n",s[m]);
 }
 printf("input k:");
 scanf("%d",&k);
 printf("s[%d]=%d\n",k-1,s[k-1]);

return 0;
}

int maopao(int a[])
{
 int i,j;
 int temp;
 for(i=0;i<len;i++)
 {
  for(j=len-1;j>i;j--)
  {
   if(a[j]>a[j-1])
   {
    temp=a[j];
    a[j]=a[j-1];
    a[j-1]=temp;
   }
  }
 }
return 0;
}

主要问题出在以下几个方面:

1.函数maopao的函数声明里的参数不能写成int或者int a,一定是int a【】因为形参a【】才表示需要传入的是一个数组,而非一个int型变量

2.真正调用maopao的时候参数要写成s而不是s【】,因为这个时候s就代表数组的首地址,也就代表数组。

3.不能直接用printf(s【m】),printf是格式化的输出,必须有格式符(%。。),形式是严格规定的。同样scanf也是

4.for(j=len-1;j>i;j--)这条语句j>i,而不是j>i-1,因为这样会导致循环到j<0的情况。

5.数组名s就代表数组首元素的地址,因此形参数组名a通过传值(因为传的是指针,故传了地址)就指向了s数组的首元素,因此后面的所有操作都将改变实参数组s的元素值。

 

插入排序,按照输入大小动态分配数组,并排序,代码如下:

#include<stdio.h>
#include<stdlib.h>

int InsertionSort(int *b,int num)
{
 int key,i,j;
 
 for(j=1;j<num;j++)
 {
  key=b[j];
  i=j-1;
  while(i>=0&&b[i]>key)
  {
    b[i+1]=b[i];
    i--;
  }
  b[i+1]=key;
 }
 
 return 0; 
}


int main()
{
 int *a;
 int len,i;
 
 printf("请输入待排序元素个数:\n");
 scanf("%d",&len);
 a=(int*)malloc(len*sizeof(int));
 printf("请输入待排序元素:\n");
 
 for(i=0;i<len;i++)
 {
  scanf("%ld",&a[i]);
 }

 InsertionSort(a,len);

 for(i=0;i<len;i++)
 {
  printf("%d ",a[i]);
 }
 return 0; 
}

主要问题出在以下几个方面:

1.实现动态数组的方法

2.将输入依次读入数组的方法

3.排序的时候想象扑克插入,但是实际上并未用递归实现,而是用j的循环遍历实现已排序数组部分的逐渐扩大

4.i>=0&&b[i]>key,这两个判定一定要同时写,不能分开

while(i>=0)
  {
     if(b[i]>key)

  {

    b[i+1]=b[i];                  当b[i]<=key时,就不需要i--了,因此这样写错误

     }
     i--;
  }

while(i>=0)
  {
     if(b[i]>key)

  {

    b[i+1]=b[i];                 注意这里有一个很微妙的错误,如果i>=0但对应的b[i]<=key,那么while会出现死循环

          i--;                 

     }
   
  }

 

 归并排序

#include<stdio.h>
#include<stdlib.h>
#define MAX 1000

int Merge(int*,int,int,int);
int temp[50];

int MergeSort(int*b,int p,int r)

 int q;

 if(p<r)
 {
  q=(p+r)/2;
  MergeSort(b,p,q);
  MergeSort(b,q+1,r);
  Merge(b,p,q,r);  
 }
 
return 0;
}
int Merge(int *c,int p,int q,int r)
{
 int i,j,k,s;
 int t1[50],t2[50];

 
 for(s=0;s<q-p+1;s++)
 {
  t1[s]=c[p+s];
 }
 t1[q-p+1]=MAX;
 
 for(s=0;s<r-q;s++)
 {
  t2[s]=c[q+s+1];
 }
 t2[r-q]=MAX;
 
 i=0;
 j=0;
 for(k=p;k<r+1;k++)
 {
  if(t1[i]<=t2[j])
  {
   temp[k]=t1[i];
   i++;
  }
  else
  {
   temp[k]=t2[j];
   j++;
  }
 }
for(i=0;i<r+1;i++)
{
 c[i]=temp[i];                    //这一步将merge的中间结果写回原数组,十分关键,否则在最后一个全数组的merge整合时,前面的阶段性merge结果没起到      作用,前后两个分组各自内部还是乱的
}                                    //可以用调试结合画图仔细分析得到
return 0;
}

 

int main()
{
 int *a;
 int len,i;

 for(i=0;i<50;i++)
 {
  temp[i]=0;
 }

 printf("请输入待排序个数:\n");
 scanf("%d",&len);
 a=(int*)malloc(sizeof(int)*len);
 printf("请输入排序序列:\n");

 for(i=0;i<len;i++)
 {
  scanf("%d",&a[i]);      //调试两大法宝:printf打印当前值,debug单步运行看变量值
 }

 MergeSort(a,0,len-1);

 for(i=0;i<len;i++)
 {
  printf("%d ",temp[i]);
 }

return 0;
}

 

 选择排序:对待排序数组遍历取出最小值,放在第一个位置,然后缩小数组边界循环此操作直到最后一个元素

#include<stdio.h>
#include<stdlib.h>

int main()
{
 int len,i,min,j,temp;
 int *a;
  
 printf("请输入待排序个数:\n");
 scanf("%d",&len);
 a=(int*)malloc(sizeof(int)*len);
 printf("请输入排序序列:\n");

 for(i=0;i<len;i++)
 {
  scanf("%d",&a[i]);     
 }
 
 for(i=0;i<len;i++)
 {
 min=i;
 for(j=i+1;j<len;j++)
 {
  if (a[j]<a[min])
   min=j;
 }
 temp=a[i];
 a[i]=a[min];
 a[min]=temp;
 }

for(i=0;i<len;i++)
{
 printf("%d ",a[i]);
}

return 0;
}

 

 堆排序:通过建最大堆一个个产生当前最大值

#include <iostream>
#include <algorithm>
using namespace std;

void HeapAdjust(int *a,int i,int size)  //调整堆
{
    int lchild=2*i;       //i的左孩子节点序号
    int rchild=2*i+1;     //i的右孩子节点序号
    int max=i;            //临时变量
    if(i<=size/2)          //如果i是叶节点就不用进行调整
    {
        if(lchild<=size&&a[lchild]>a[max])
        {
            max=lchild;
        }   
        if(rchild<=size&&a[rchild]>a[max])
        {
            max=rchild;
        }
        if(max!=i)
        {
            swap(a[i],a[max]);
            HeapAdjust(a,max,size);    //避免调整之后以max为父节点的子树不是堆
        }
    }       
}

void BuildHeap(int *a,int size)    //建立堆
{
    int i;
    for(i=size/2;i>=1;i--)    //非叶节点最大序号值为size/2
    {
        HeapAdjust(a,i,size);   
    }   
}
void Swap(int *a, int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
void HeapSort(int *a,int size)    //堆排序 
{
    int i;
    BuildHeap(a,size);
    for(i=size;i>=1;i--)
    {
        //cout<<a[1]<<" ";
        swap(a[1],a[i]);           //交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面
          //BuildHeap(a,i-1);        //将余下元素重新建立为大顶堆
          HeapAdjust(a,1,i-1);      //重新调整堆顶节点成为大顶堆
    }
}

int main(int argc, char *argv[]) 

   int *arr;

   printf("请输入待排序个数:\n");
   scanf("%d",&len);
   arr=(int*)malloc(sizeof(int)*len);
   printf("请输入排序序列:\n");    
   for(i=0;i<len;i++)
     cin>>a[i];
   HeapSort(arr, len);

   int i = 0;

   for( i = 0; i < len; i++)

   cout<<a[i]<<"";
        cout<<endl;  

return 0;

}

 

posted on 2012-03-10 00:42  拓扑玩  阅读(234)  评论(0)    收藏  举报