C中排序與查找

編程中的排序方法:冒泡、選擇、插入、快速排序、哈希、shell等

一、冒泡排序

/*********************冒泡排序********************/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<math.h>
#include<sys/types.h>
void maopao(int *a,int n)
{
    int i,j,temp;
    for(i=0;i<n;i++)
    {
        for(j=0;j<n-1-i;j++)
        {
            if(a[j]>a[j+1])
            {
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
    }
}
void show(int *a,int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%-3d",a[i]);
    }
    printf("\n");
}
int main (void)
{
    int a[10] = {12,23,10,14,8,22,43,1,3,0};
    maopao(a,10);
    show(a,10);
    return 0;
}

二、選擇排序

/***********************************選擇排序***********************************/
void choise(int *a,int n)
{
    int i,j,temp;
    for(i=0;i<n-1;i++)
    {
        for(j=i+1;j<n;j++)
        {
            if(a[i]>a[j])
            {
                temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }
}
void show(int *a,int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%-3d",a[i]);
    }
    printf("\n");
}
int main (void)
{
    int a[10] = {10,14,8,22,94,95,4,5,6,1};
    choise(a,10);
    show(a,10);
    return 0;
}

三、插入排序 

          插入法:
                     插入法是一種比較直觀的排序方法;
                     它首先把數組頭兩個元素排好序,
                     再依次把後面的元素插入適當的位置,
                     把數組元素插完也就完成了排序。

/***********************插入排序***************************/
/**
 ** 插入法:
 ** 插入法是一種比較直觀的排序方法。
 ** 它首先把數組頭兩個元素排好序,
 ** 再依次把後面的元素插入適當的位置。
 ** 把數組元素插完也就完成了排序。
 **/
void insert(int *a,int n)
{
    int i,j,temp;
    for(i=1;i<n;i++)
    {
        temp = a[i];/*temp爲要插入的元素*/
        j = i - 1;
        /*從a[i-1]開始找比a[i]小的數,同時把數組元素向後移*/
        while(j>=0 && temp<a[j])
        {
            a[j+1] = a[j];
            j--;
        }
        a[j+1] = temp;/*插入*/
    }
}
void show(int *a,int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%-3d",a[i]);
    }
    printf("\n");
}
int main (void)
{
    int a[10] = {12,2,4,67,32,45,22,11,90,15};
    insert(a,10);
    show(a,10);

    return 0;
}

四、快速排序

             快速法定義了三個參數(數組首地址*a,要排序數組起始元素下標i,要排序數組結束元素下標j)
             它首先選一個數組元素(一般爲a[(i+j)/2],即中間元素)作爲參照,
             把比它小的元素放到它的左邊,比它大的放在右邊。
             然後運用遞歸,在將它左,右兩個子數組排序,
             最後完成整個數組的排序。

/**********快速排序*********************/
/**       
 ** 快速法定義了三個參數,
 **(數組首地址*a,要排序數組起始元素下標i,要排序數組結束元素下標j)
 ** 它首先選一個數組元素(一般爲a[(i+j)/2],即中間元素)作爲參照,
 ** 把比它小的元素放到它的左邊,比它大的放在右邊。
 ** 然後運用遞歸,在將它左,右兩個子數組排序,
 ** 最後完成整個數組的排序。
 **/
void quick(int *a,int i,int j)
{
    int m,n,temp;
    int k;
    m=i;
    n=j;
    k=a[(i+j)/2]; /*選取的參照*/
    while(m<=n)
    {
        while(a[m]<k&&m<j) m++; /* 從左到右找比k大的元素*/
        while(a[n]>k&&n>i) n--; /* 從右到左找比k小的元素*/
        if(m<=n) { /*若找到且滿足條件,則交換*/
                  temp=a[m];
                  a[m]=a[n];
                  a[n]=temp;
                  m++;
                  n--;
                 }
    }
    if(m<j) quick(a,m,j); /*運用遞歸*/
    if(n>i) quick(a,i,n);
}
int show(int *a,int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%-3d",a[i]);
    }
    printf("\n");
    return 0;
}
int main (void)
{
    int a[10] = {23,13,1,4,2,56,78,22,10,3};
    quick(a,0,9);
    show(a,10);
    return 0;
}

五、shell排序

              shell法:
                           shell法是一個叫 shell 的美國人與1969年發明的。
                           它首先把相距k(k>=1)的那幾個元素排好序,再縮小k值(一般取其一半)
                           再排序,直到k=1時完成排序。下面讓我們來分析其代碼
 

/******************shell排序**********************/
/**
 **shell法是一個叫 shell 的美國人與1969年發明的。
 **它首先把相距k(k>=1)的那幾個元素排好序,再縮小k值(一般取其一半)
 **再排序,直到k=1時完成排序。下面讓我們來分析其代碼
 **/
void shell(int *a,int n)
{
    int i,j,k,temp;
    k = n/2;
    while(k>=1)
    {
        for(i=k;i<n;i++) {
            temp = a[i];
            j=i-k;
            while(j>=0 && temp<a[j]) {
                a[j+k]=a[j];
                j-=k;
            }
            a[j+k]=temp;
        }
        k/=2; /*縮小間距值*/
    }
}
void show(int *a,int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        printf("%-3d",a[i]);
    }
    printf("\n");
}
int main (void)
{
    int a[10] = {12,19,95,94,10,14,8,22,1,4};
    shell(a,10);
    show(a,10);
    return 0;
}

折半查找(二分查找)

    折半查找需要數據爲有序數據

代碼如下:

#include <stdio.h>
int Binary_search(int *a,int n,int obj)
{
	int low,hight,mid;
	low = 0;
	hight = n;
	mid = (low+hight)/2;
	while(low<=hight)
	{
		mid = (low+hight)/2;
		if(obj < a[mid])
			hight = mid - 1;
		else if(obj > a[mid])
		{
			low = mid + 1;
		}
		else
			return mid;
	}
	return 0;
}
int main()
{
	int a[10] = {1,2,3,4,5,6,7,8,9,10};
	int temp = Binary_search(a,10,5);
	printf("temp = %d\n",temp);
	return 0;
}

插值查找

      插值查找比折半查找更快

 折半查找循環中的  mid = (low+hight)/2 = low + 1/2(hight - low);
 也就是mid等於最低下標low加上最高下標hight與low的差的一半.算法工程師考慮的就是將這個1/2進行改進,改進爲下的計算方案:
mid = low + (obj - a[low])/(a[hight] - a[low])*(hight - low);

插值查找代碼如下:

int Binary_search(int *a,int n,int obj)
{
	int low,hight,mid;
	low = 0;
	hight = n;
	mid = (low+hight)/2;
	while(low<=hight)
	{
		mid = low + (obj - a[low])/(a[hight] - a[low])*(hight - low);
		if(obj < a[mid])
			hight = mid - 1;
		else if(obj > a[mid])
		{
			low = mid + 1;
		}
		else
			return mid;
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章