常见算法
一、数组排序
选择排序、插入排序、交换排序
1.直接插入排序
将待排序的数按大小,插到前面排好数据的适当位置。
11,8,1,10,7,4,12,2,3,6,5,9
实现方法:在已排数据中,只要比待排大,则向后移动一格,在这个大数据倒出一个空格,直到比这个待排的小为止,最后将待排的插入到空格处.
int main(int argc,char **argv){
int a[]={1,12,11,8,10,7,4,2,3,6,5,9};
int i,j,n=12;
for(i=1;i<n;i++){//要排数的下标
int tmp=a[i]; //将待排的元素保存到临时变量中
j=i-1;
while(j>=0 && a[j]>tmp){ //j代表已排的下标
a[j+1]=a[j]; //元素向后移动
j--; //下标递减
}
a[j+1]=tmp;//赋给空出位置的元素
}
for(i=0;i<n;i++) printf("%d ",a[i]);
}
2.直接选择排序法
是从待排序的数据中选出最小的值,顺序存放在已排序的数据后面
int main(int argc,char **argv){
int a[]={11,8,1,10,7,4,12,2,3,6,5,9};
int i,j,n=12;
for(i=0;i<n;i++){ //i代表已排序后面的数的下标
int min=i;
for(j=i;j<n;j++){//在待排序数中找到最小的下标
if (a[min] > a[j]) min=j;
}
//如果找到的最小的和已排序后面数的值不同,则换
if (a[i]>a[min]){
int tmp=a[i];
a[i]=a[min];
a[min]=tmp;
}
}
for(i=0;i<n;i++) printf("%d ",a[i]);
}
3.冒泡排序(交换排序)
两两比较待排序数,交换不满足顺序的两个数
int main(int argc,char **argv){
int a[]={11,8,1,10,7,4,12,2,3,6,5,9};
int i,j,n=12;
for(i=1;i<n;i++){ //i代表第i轮 共n-1轮
for(j=0;j<n-i;j++){ //j代表下标 共比较n-i次
if (a[j] >a[j+1]){
int tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
for(i=0;i<n;i++) printf("%d ",a[i]);
}
二、链表排序
1.改内容
不可取
2.改变链表的链接 (了解)
struct Num{
int n;
struct Num *next;
} *head,*tail;
struct Num* creat(int n){
struct Num *p=(struct Num*)malloc(sizeof(struct Num));
p->n=n;
p->next=NULL;
return p;
}
void add(struct Num *p){
if (head==NULL) head=p;
else tail->next=p;
tail=p;
}
void print(){
struct Num *p=head;
while(p!=NULL){
printf("%d ",p->n);
p=p->next;
}
printf("\n");
}
void sort(){
struct Num *nhead=NULL,*ntail;
while(head!=NULL){
//找最小的地址
struct Num *min=head,*premin=NULL,*p=head,*p1=NULL;
while(p!=NULL){
if (min->n >p->n) {
premin=p1; //最小值的前一个地址
min=p; //最小值的地址
}
p1=p;
p=p->next;
}
//将结构体从原链中摘除
if (premin==NULL) head=min->next;//如果要摘的是头,则确定新头
else premin->next=min->next;
//新链尾插
if (nhead==NULL) nhead=min;
else ntail->next=min;
ntail=min;
}
//将新的头和尾,重新保存到原的头和尾变量内
head=nhead;
tail=ntail;
}
int main(int argc,char **argv){
int a;
while(1){
scanf("%d",&a);
if (a==-1) break;
struct Num* p=creat(a);
add(p);
}
//------------------
print();
sort();
print();
}
2.建立索引表 ****
struct Num** sort(int *gs){
//将结构体的地址保存到数组中
struct Num *p=head,**a=(struct Num**)malloc(count * 4);//索引表
int i=0,j;
while(p!=NULL) {
a[i++]=p;
p=p->next;
}
//排序
for (i=1;i<count;i++){
for(j=0;j<count-i;j++){
if (a[j]->n > a[j+1]->n){
struct Num *tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
}
}
*gs=count;
return a;
}
int main(int argc,char **argv){
int a;
while(1){
scanf("%d",&a);
if (a==-1) break;
struct Num* p=creat(a);
add(p);
}
//------------------
print();
int i,n;
struct Num **b=sort(&n);
for(i=0;i<n;i++) printf("%d ",b[i]->n);
free(b);
}
三、查找
1.无序数组查找
1,11,8,10,7,4,12,2,3,6,5,9
找到 3 并打印
依次遍历(即从头到尾来比较)
2.有序数组查找
1 2 3 4 5 6 7 8 9 10 11 12
二分法,也称折半法
int main(int argc,char **argv){
int a[]={1,2,3,4,5,6,7,8,9,10,11,12};
int b=atoi(argv[1]);
int min=0,max=11,mid;
int sign=0; //1代表找到 0没找到
while(min<=max && !sign){
mid=(min+max)/2;
if (a[mid]b) sign=1; //找到了 mid就是要找的值的下标
else if (a[mid] > b) max=mid-1;
else min=mid+1;
}
if (sign1) printf("---- %d\n",a[mid]);
else printf(“没找到\n”);
}
3.链表查找
1)无序链表
遍历
2)有序链表
遍历
3)索引表(哈希)
同数组二分法
4.将链表保存到文件
struct Num{
int n;
struct Num *next;
} *head,*tail;
int count;
struct Num* creat(int n){
count++;
struct Num *p=(struct Num*)malloc(sizeof(struct Num));
p->n=n;
p->next=NULL;
return p;
}
void add(struct Num *p){
if (head==NULL) head=p;
else tail->next=p;
tail=p;
}
void print(){
struct Num *p=head;
while(p!=NULL){
printf("%d ",p->n);
p=p->next;
}
printf("\n");
}
int msave(char *file){
FILE *fp=fopen(file,"w");
if (fp==NULL) return -1;
struct Num *p=head;
while(p!=NULL){
fwrite(p,sizeof(struct Num),1,fp);
p=p->next;
}
fclose(fp);
return 0;
}
int mopen(char *file){
FILE *fp=fopen(file,"r");
if (fp==NULL){
printf("---- open err=%s\n",strerror(errno));
return -1;
}
fseek(fp,0,2);
int i=0,n=ftell(fp)/sizeof(struct Num);
fseek(fp,0,0);
while(i<n){
struct Num *p=(struct Num*)malloc(sizeof(struct Num));
fread(p,sizeof(struct Num),1,fp);
p->next=NULL;
add(p);
i++;
}
fclose(fp);
return 0;
}
int main(int argc,char **argv){
int err= mopen(argv[1]);
if (err==0){
print();
}
else {//失败
int a;
while(1){
scanf("%d",&a);
if (a==-1) break;
struct Num* p=creat(a);
add(p);
}
msave(argv[1]);
}
}