一、C结构体定义的一个错误
expected primary-expression before ‘[’ token
刚刚的一个结构体定义时候出现的错误
比如刚刚写的代码是酱婶儿的
typedef struct student{
char name[];
int score;
}stu[1010];
for(i=1;i<=n;i++){
scanf("%d",&stu[i].score);//这个地方报错
}
是指缺少申明,需要申明变量
修正:
typedef struct student{
char name[];
int score;
}student;
student stu[1010];
for(i=1;i<=n;i++){
scanf("%d",&stu[i].score);//这个地方报错
}
二、复习快排
敲了几遍终于没问题了。。。。直接上源代码
#include<stdio.h>
int Swap(int a[],int low,int high) //写一个交换函数
{
int t;
t=a[low];
a[low]=a[high];
a[high]=t;
}
int Partition(int a[],int low,int high)//核心排序
{
int base=a[low];//以最左侧的数为基准值
while(low < high)
{
while(a[high]>=base && low<high)//首先从右往左查,不然会出错
{
high--;
}
Swap(a,low,high);//当小于基准值时交换
while(a[low]<=base && low<high)//从左往右
{
low++;
}
Swap(a,low,high);//交换
}
return low;//返回下标(用于二分
}
int QuickSort(int a[],int low,int high)
{
if(low < high)//注意前提条件low < high
{
int base = Partition(a,low,high);//这里的base是个下标值
QuickSort(a,low,base-1);//对枢纽左侧进行排序
QuickSort(a,base+1,high);//对枢纽右侧进行排序
}
}
int main()
{
int a[1010];
int n;
scanf("%d",&n);
int i;
int j;
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
QuickSort(a,0,n-1);
for(j=0;j<n;j++)
{
printf("%d ",a[j]);
}
return 0;
}
调用三个函数,分别是:swap(交换) partition(二分)←核心 quicksort(实现递归)
三、约瑟夫环
借用约瑟夫环复习了一下结构体指针。
贴上来源代码
//n个小孩手拉手,从1报数,第m个人出列,再继续从1报数,直到剩最后一个人为止,输出是几号
#include<stdio.h>
#include<stdlib.h>
typedef struct link{
int pos;//代号
struct link *next;//一个next指针域
}link;
link *creatlist(int n){
link *head;//头指针
link *tail;//尾指针
link *node;//结点指针
head=(link *)malloc(sizeof(link));
tail=head;
for(int i=1;i<=n;i++){
node=(link *)malloc(sizeof(link));
node->pos = i;//赋代号值
tail->next=node;//连接上一个结点和这个新创建的结点
node->next=NULL;//别忘了把新的结点的next域置为空
tail=node;//尾指针移动到新的结点上
}
tail->next=NULL;//别忘把最后一个结点的next域置为空
return head;//返回头结点,该链表建立完成
}
void deletelist(link *p,int x){
int i=0;//注意这个是0而不是1,因为从头结点开始动
link *t;//记录前驱结点
while(p!=NULL && i!=x){
t=p;
p=p->next;
i++;
}
if(p!=NULL){
t->next=p->next;
free(p);
}
}
int main(){
int n,m,count;
link *p;
while(scanf("%d%d",&n,&m)){
p=creatlist(n);
count=0;//这里的count指的是每轮下来淘汰的人数
int i;//记录到第几号了
int j;//记录第几个人(跟m有关
for(i=1,j=1;n>1;i++,j++){
if(n-count==1) break;
if(j==m){
deletelist(p,i-count);
j=0;//置0不是置1,之后j会自增
count++;
}
if(i==n){//如果进行了一圈
i=i%n;
n-=count;//减去这一圈out的人数
count=0;
}
}
printf("%d\n",p->next->pos);//p的这个时候在头结点位置
free(p);
}
return 0;}
(我觉得这个我还得多敲几遍…
四、hash表
1、散列技术:
在记录的存储位置和它的关键字之间建立一个确定的相应关系f。使得每一个关键字key相应一个存储位置f(key)。散列技术既是一种存储方法,也是一种查找方法。
散列技术适合求解问题是查找与给定值相等的记录。查找速度快。
散列技术不适合范围查找,不适合查找相同关键字的记录,不适合获取记录的排序,最值。
关关键字相应的记录存储位置称为散列地址。
重点:需要解决冲突:关键字key1不等于key2。但f(key1)=f(key2)。
个人理解就是一堆数据,每个数据都取一个和数据相关的名字,方便查找,时间复杂度降为O(1)。但有冲突点,可能会有两个或多个数据的名字一样,即存储位置有冲突,重点着手于如何处理冲突。
2.散列函数的构造:
原则:1计算简单 2散列地址分布均匀
a.直接定址法
f(key)=a x key+b(a、b为常数)
适合查找表小且连续。
b.数字分析法
适合关键字位数多且若干位分布均匀的数据。
c.平方折中法
1234,平方1522756。抽取中间227作为散列地址。
不知道关键字分布,且位数不是非常大。
d.折叠法
从左到右切割成位数相等的几部分,这几部分叠加求和,并按散列表表长,取后几位作为散列地址。
不知道关键字分布,位数多。
e.除留余数法
f(key)=key mod p(p<=m)
p选取不好容易产生冲突。
通常p为<=m(最好接近m)的最小质数或者不包括小于20质因子的合数。
f.随机数法
f(key)=random(key),random随机函数
当关键字为字符串,转化为某种数字来对待。比方ASCLL码或者Unicode码等。
适合关键字长度不等的数据。
其实我觉得上面摘的这些除了凑字数没啥太多用处…实际应用的时候根据所给数据咋方便咋来
3如何解决冲突问题
a.开放定址法
意思是一旦冲突,寻找下一个空的散列地址
b.链地址法
将全部关键字为同义词的记录存储在一个单链表(同义词字表)中。
散列表中仅仅存储全部同义词字表的头指针。
c. 公共溢出区法
把冲突的关键字统一都放到一块去存储起来,也就是溢出表。散列计算后,先基本表比較。不等,到溢出表进行顺序查找。