数据结构之(顺序查找、折半查找、hash查找、直接插入排序、折半插入排序、链表插入排序、shell排序、冒泡排序、快速排序)
顺序查找
#include<stdio.h>
#define N 10
int seqsearch(int *a,int key);
int main(int argc, const char *argv[])
{
int a[]={12,2,3,5,2,8,7,6,9,11};
int i,key;
char ch;
while(1)
{
printf("please input key:");
scanf("%d",&key);
i=seqsearch(a,key);
if(i==-1)
puts("search error!");
else
printf("search %d at %d\n",key,i);
printf("continue?(Y/y):");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
continue;
else
break;
}
return 0;
}
int seqsearch(int *a,int key)
{
int i;
for(i=N-1;i>=0;i--)
{
if(key==a[i])
return i;
}
return -1;
}
折半查找
#include<stdio.h>
#define N 12
int binsearch(int *a,int key);
int main(int argc, const char *argv[])
{
int a[]={3,12,18,20,32,55,60,68,80,86,90,100};
int i,key;
char ch;
while(1)
{
printf("please input key:");
scanf("%d",&key);
i=binsearch(a,key);
if(i==-1)
puts("search error!");
else
printf("search %d at %d\n",key,i);
printf("continue?(Y/y):");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
continue;
else
break;
}
return 0;
}
int binsearch(int *a,int key)
{
int low,high,mid;
low=0;
high=N-1;
while(low<=high)
{
mid=(low+high)/2;//找到中间位置
if(a[mid]==key)
return mid;//查找成功,返回mid
else if(key<a[mid])
high=mid-1;//如果key<mid位置记录的key,则让high=mid-1;
else
low=mid+1;//如果key>mid位置记录的key,则让low=mid+1;
}
return -1;//查找失败,返回-1
}
hash查找-开放地址处理冲突
hash.h
#ifndef __HASH_H__
#define __HASH_H__
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#define N 11
typedef int datatype;
typedef struct hashtbl{
datatype *h;
int length;
}hash_tbl,*hash_tp;
extern void init_hash(hash_tp *Hp,int m);
extern void create_hash(hash_tp hp,datatype *a);
extern int fun(int m);
extern int hash_search(hash_tp hp,int key);
extern void hash_show(hash_tp hp);
#endif
hash.c
#include "hash.h"
void init_hash(hash_tp *Hp,int m)
{
(*Hp)=(hash_tp)malloc(sizeof(hash_tbl));
if(NULL==*Hp)
{
perror("malloc");
exit(-1);
}
(*Hp)->length=m;
(*Hp)->h=(datatype*)malloc((*Hp)->length*sizeof(datatype));
if(NULL==(*Hp)->h)
{
perror("Malloc");
exit(-1);
}
int i;
for(i=0;i<(*Hp)->length;i++)
{
(*Hp)->h[i]=-1;
}
}
int fun(int m)
{
int i;
for(;m>1;m--)
{
for(i=2;i<m;i++)
if(m%i==0)
{
break;
}
if(i>=m)
return m;
}
return -1;
}
void create_hash(hash_tp hp,datatype *a)
{
int hash_val,i,p;
p=fun(hp->length);
if(p==-1)
exit(-1);
for(i=0;i<N;i++)
{
//1、用除留余数法构建hash函数
hash_val=a[i]%p;
//2、用线性探查法处理冲突
while((hp->h[hash_val])!=-1)
hash_val=(hash_val+1)%hp->length;
//3、将记录存储在hash_val的位置
hp->h[hash_val]=a[i];
// hash_show(hp);
}
}
int hash_search(hash_tp hp,int key)
{
int hash_val,flag,p;
p=fun(hp->length);
hash_val = key %p;//用除留余数法得到hash地址
while((hp->h[hash_val])!=key)
{
hash_val = (hash_val+1)%hp->length;
flag++;
if(flag==hp->length)
return -1;
}
return hash_val;
}
void hash_show(hash_tp hp)
{
int i;
for(i=0;i<hp->length;i++)
{
printf("hp->h[%02d]:%d\n",i,hp->h[i]);
}
printf("*************************************\n");
}
int main(int argc, const char *argv[])
{
hash_tp hp;
int m,i,key;
char ch;
int a[]={23,34,14,38,46,16,68,15,7,31,26};
//1、根据记录个数得到hash表的长度
m=(int)ceil(N/0.75);
//2、初始化hash表空间
init_hash(&hp,m);
//3、创建hash表
create_hash(hp,a);
//4、hash表查找
while(1)
{
printf("please input key:");
scanf("%d",&key);
i=hash_search(hp,key);
if(i==-1)
puts("search error!");
else
printf("search %d at %d\n",key,i);
printf("continue?(Y/y):");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
continue;
else
break;
}
return 0;
}
hash查找-链地址处理冲突
hash.h
#ifndef __HASH_H__
#define __HASH_H__
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#define N 11
typedef int datatype_el;
typedef struct listnode
{
datatype_el data;
struct listnode *next;
}list_node,*list_pnode;
typedef list_pnode datatype;
typedef struct hashtbl{
datatype *h;
int length;
}hash_tbl,*hash_tp;
extern void init_hash(hash_tp *Hp,int m);
extern void create_hash(hash_tp hp,datatype_el *a);
extern int fun(int m);
extern list_pnode hash_search(hash_tp hp,int key);
extern void hash_show(hash_tp hp);
#endif
hash.c
#include "hash.h"
void init_hash(hash_tp *Hp,int m)
{
(*Hp)=(hash_tp)malloc(sizeof(hash_tbl));
if(NULL==*Hp)
{
perror("malloc");
exit(-1);
}
(*Hp)->length=m;
(*Hp)->h = (datatype *)malloc(((*Hp)->length) * sizeof(datatype));
if(NULL==(*Hp)->h)
{
perror("Malloc");
exit(-1);
}
int i;
for(i=0;i<(*Hp)->length;i++)
{
(*Hp)->h[i]=NULL;
}
}
int fun(int m)
{
int i;
for(;m>1;m--)
{
for(i=2;i<m;i++)
if(m%i==0)
{
break;
}
if(i>=m)
return m;
}
return -1;
}
void create_hash(hash_tp hp,datatype_el *a)
{
int hash_val,i,p;
list_pnode new;
p=fun(hp->length);
if(p==-1)
exit(-1);
for(i=0;i<N;i++)
{
//1、用除留余数法构建hash函数,用链地址法处理冲突
hash_val=a[i]%p;
//2、申请结点空间
new=(list_pnode)malloc(sizeof(list_pnode));
if(new==NULL)
{
perror("malloc");
exit(-1);
}
new->data=a[i];
//3、将记录存储在hash_val的位置
new->next=hp->h[hash_val];
hp->h[hash_val]=new;
hash_show(hp);
sleep(1);
}
}
list_pnode hash_search(hash_tp hp,int key)
{
int hash_val,p;
list_pnode tp;
p=fun(hp->length);
hash_val = key %p;//用除留余数法得到hash地址
for(tp=hp->h[hash_val];tp!=NULL;tp=tp->next)
if(tp->data==key)
return tp;
return NULL;
}
void hash_show(hash_tp hp)
{
list_pnode tp;
int i;
for(i=0;i<hp->length;i++)
{
printf("hp->h[%02d]:",i);
for(tp=hp->h[i];tp!=NULL;tp=tp->next)
printf("---->%d",tp->data);
puts("");
}
}
int main(int argc, const char *argv[])
{
hash_tp hp;
int m,key;
char ch;
list_pnode ret;
datatype_el a[]={23,34,14,38,46,16,68,15,7,31,26};
//1、根据记录个数得到hash表的长度
m=(int)ceil(N/0.75);
//2、初始化hash表空间
init_hash(&hp,m);
//3、创建hash表
create_hash(hp,a);
//4、hash表查找
while(1)
{
printf("please input key:");
scanf("%d",&key);
ret=hash_search(hp,key);
if(ret==NULL)
puts("search error!");
else
printf("search %d : %d\n",key,ret->data);
printf("continue?(Y/y):");
while(getchar()!='\n');
scanf("%c",&ch);
if(ch=='y'||ch=='Y')
continue;
else
break;
}
return 0;
}
直接插入排序
#include<stdio.h>
#define N 8
void show(int a[]);
void seqsearch(int a[]);
int main(int argc, const char *argv[])
{
int a[]={50,36,66,76,95,12,25,36};
puts("原无序记录如下:");
show(a);
puts("排序过程如下:");
seqsearch(a);
puts("有序记录如下:");
show(a);
return 0;
}
void show(int a[])
{
int i;
for(i=0;i<N;i++)
printf("%d\t",a[i]);
puts("");
}
void seqsearch(int a[])
{
int i,j,tmp;
for(i=1;i<N;i++)
{
tmp=a[i];
for(j=i-1;j>=0;j--)
{
if(tmp<a[j])
a[j+1]=a[j];
else
break;
}
a[j+1]=tmp;
show(a);
}
}
折半插入排序
#include<stdio.h>
#define N 8
void show(int a[]);
void binsearch(int a[]);
int main(int argc, const char *argv[])
{
int a[]={50,36,66,76,95,12,25,36};
puts("原无序记录如下:");
show(a);
puts("排序过程如下:");
binsearch(a);
puts("有序记录如下:");
show(a);
return 0;
}
void show(int a[])
{
int i;
for(i=0;i<N;i++)
printf("%d\t",a[i]);
puts("");
}
void binsearch(int a[])
{
int i,j,tmp,low,high,mid;
for(i=1; i<N ; i++)
{
tmp=a[i];//无序记录中的数据保存到tmp中
//在有序的记录中利用折半查找算法,寻找插入位置
for(low = 0,high=i-1;low<=high;)
{
mid =(low+high)/2;
if(tmp<a[mid])
high=mid-1;
else
low=mid+1;
}
for(j=i;j>low;j--)
{
a[j]=a[j-1];
}
a[low]=tmp;
show(a);
}
}
链表插入排序
linklist.h
#ifndef __LIST_H__
#define __LIST_H__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef int datatype;
typedef struct listnode{
datatype data;
struct listnode *next;
}list_node,*list_pnode;
extern void init_linklist(list_pnode *H);
extern void create_linklist(list_pnode h);
extern void show_linklist(list_pnode h);
extern void link_sort(list_pnode h);
#endif
linklist.c
#include "linklist.h"
void init_linklist(list_pnode *H)
{
*H=(list_pnode)malloc(sizeof(list_node));
if(NULL == *H)
{
printf("malloc failed\n");
exit(1);
}
(*H)->next = NULL;
}
void create_linklist(list_pnode h)
{
int n,i;
list_pnode new,p;
printf(" 请输入链表长度:");
scanf("%d",&n);
printf(" 请输入链表中存入的数据:\n");
for(i=0,p=h;i<n;i++)
{
new=(list_pnode)malloc(sizeof(list_node));
if(NULL==new)
{
printf("malloc failed\n");
exit(1);
}
scanf("%d",&new->data);
new->next = p->next;
p->next=new;
p=p->next;
}
}
void show_linklist(list_pnode h)
{
list_pnode p;
for(p=h->next;p;p=p->next)
{
printf("%2d\t",p->data);
}
puts("");
}
void link_sort(list_pnode h)
{
list_pnode p,q,t1,t2;
//将链表分成两部分
p=h->next;
h->next=NULL;
//按顺序将数据逐个插入到有序的链表中
while(p!=NULL)
{
q=p;
p=p->next;
//在有序的链表中寻找插入q指向的结点的位置
t1=h;
t2=h->next;
while(t2!=NULL && q->data>t2->data)
{
t1=t2;
t2=t2->next;
}
//将q指向的结点插入到t1和t2之间
q->next=t2;
t1->next=q;
// show_linklist(h);
}
}
int main(int argc, const char *argv[])
{
list_pnode h;
init_linklist(&h);
create_linklist(h);
printf("创建如下链表:");
show_linklist(h);
link_sort(h);
printf("排序后的链表:");
show_linklist(h);
return 0;
}
shell排序
#include<stdio.h>
#define N 10
void show(int a[]);
void shellsort(int a[]);
int main(int argc, const char *argv[])
{
int a[]={50,36,66,76,95,12,25,36,24,8};
puts("原无序记录如下:");
show(a);
puts("排序过程如下:");
shellsort(a);
puts("有序记录如下:");
show(a);
return 0;
}
void show(int a[])
{
int i;
for(i=0;i<N;i++)
printf("%d\t",a[i]);
puts("");
}
void shellsort(int a[])
{
int i,j,tmp;
int d;
for(d=N/2;d>0;d/=2)
{
for(i=d;i<N;i++)
{
tmp=a[i];
for(j=i-d;j>=0;j-=d)
{
if(tmp<a[j])
a[j+d]=a[j];
else
break;
}
a[j+d]=tmp;
}
show(a);
}
}
冒泡排序
#include<stdio.h>
#define N 10
void show(int a[]);
void bubble(int a[]);
int main(int argc, const char *argv[])
{
# if 1
int a[N]={50,36,66,76,95,12,25,36,24,8};
# else
int a[N]={11,22,33,44,55,66,77,88,99,111};
#endif
printf("原无序记录如下:\n");
show(a);
printf("排序过程如下:\n");
bubble(a);
printf("有序记录如下:\n");
show(a);
return 0;
}
void bubble(int a[])
{
int i,j,tmp,flag;
for(i=0;i<N-1;i++)
{
flag=1;
for(j=0;j<N-1-i;j++)
if(a[j]>a[j+1]){
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
flag=0;
}
if(flag)//对冒泡排序算法的改进
break;
show(a);
}
}
void show(int a[])
{
int i;
for(i=0;i<N;i++)
printf("%d\t",a[i]);
puts("");
}
快速排序
#include<stdio.h>
#define N 8
void show(int a[]);
void quicksort(int a[],int low,int high);
int quickpass(int a[],int i,int j);
int main(int argc, const char *argv[])
{
# if 1
int a[N]={50,36,66,76,36,12,25,95};
# else
int a[N]={11,22,33,44,55,66,77,88,99,111};
#endif
printf("原无序记录如下:\n");
show(a);
printf("排序过程如下:\n");
quicksort(a,0,N-1);
printf("有序记录如下:\n");
show(a);
return 0;
}
//一趟快速排序
int quickpass(int a[],int i,int j)
{
int tmp;
tmp=a[i];//将a[i]作为基准保存
while(i<j)
{
//从上界比较
while(i<j&&tmp<=a[j])
j--;
//将a[i]交换到左边
if(i<j)
a[i]=a[j];
//从下界比较
while(i<j&&tmp>=a[i])
i++;
//将a[i]交换到右边
if(i<j)
a[j]=a[i];
}
a[i]=tmp;//将基准放到最终的位置
return i;//返回基准的下标
}
void quicksort(int a[],int low,int high)
{
int mid;
if(low<high)
{
mid=quickpass(a,low,high);//一趟快速排序
show(a);
quicksort(a,low,mid-1);//基准左边序列进行快速排序
quicksort(a,mid+1,high);//基准右边序列进行快速排序
}
}
void show(int a[])
{
int i;
for(i=0;i<N;i++)
printf("%d\t",a[i]);
puts("");
}