1.使用c语言描述数据结构以及算法的定义和设计
1.1C语言的数据类型
数据类型明确地或默认地规定了在程序执行期间参加运算的变量或表达式所有可能的取值范围以及在这些值上允许进行的操作。对于内置数据类型,如int、char、float 等这些数据类型都是我们在C语言中常见的数据类型,而对于数据结构,我们需要重点讨论的是构造型、联合型和指针型。
1.构造型struct
构造型是程序员自己定义的数据类型,它本身又包含了若干不同的成分,每一成分又具有自己的数据类型。现在定义一个简单的数据类型来理解构造性这一数据类型。
//考生的构造性定义
typedef struct{ //结构类型声明
long number; //考生号(长整型)
char name; //姓名(字符型)
float score; //成绩(浮点型)
int code; //录取学校编码(整形)
}Examinee; //考生的类型名
题外话,先解释一下typedef吧,typedef 也是C语言的关键字,作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)
2.联合型union
联合型也称为共存型,它也是程序员自己定义的数据类型,与构造型类似,它也包含若干不同成分。与构造型的区别在于,联合型所包含的这些成分共享同一空间,就是说,这些成分覆盖了同一块存储空间。如果把程序1-2中的保留字struct改成union,则它的所有成分将叠压在同一块存储空间。
3.指针型
指针存储的不是数据元素的内容,而是数据元素的地址。指针必须有类型,该类型用以说明该指针所指示的对象的类型。例如,char类型的指针指向的地址存放的应是char类型的数据(原子型),Examinee类型的指针指向的地址存放的应是Examinee类型的数据(构造型)。因此,指针变量的类型与它所指向的数据的类型必须一致。举个例子说明指针型的用法吧,通过int *p定义一个指针型变量p,通过b=&p存储b的地址,如果想对b进行赋值操作则令 *p=25。
3.1指针和数组地址关系
数组名可以作为数组第一个元素的指针。我们由数组和指针的关系知道,a代表这个地址数值,它相当于一个指针,指向第一个元素(&a[0]),即指向数组的首地址。数组中的其他元素可以通过a的位移得到,此时的进阶是以数组中单个的元素类型为单位的,即a+i= & a[i]。
3.2&跟*之间的关系
取地址运算符&:单目运算符&是用来取操作对象的地址。例:&i 为取变量 i 的地址。对于常量表达式、寄存器变量不能取地址(因为它们存储在存储器中,没有地址)。
指针运算符*(解引用运算符 ):与&为逆运算,作用是通过操作对象的地址,获取存储的内容。例:x = &i,x 为 i 的地址,*x 则为通过 i 的地址,获取 i 的内容。
注意在使用指针的时候要注意以下几点,防止野指针(不正确的指针)
<1>指针初始化
<2>.小心指针越界
<3>指针指向空间释放即置NULL
<4>指针使用之前检查有效性
1.2算法的控制结构
算法描述的三大控制结构是顺序型、选择型、重复型。
<1>顺序型
算法中的语句顺序执行。
<2>选择型
其形式跟我们在c语言中见到的其实一样
(1)if(条件表达式) 语句1 else 语句二
(2)else部分为空的两分支选择型,其形式为
if(条件表达式) 语句1;
(3)switch(计算表达式)
case 值 1: 语句序列;break;
.
.
.
case 值 n: 语句序列;break;
default ui据序列n+1;
(4)条件赋值型
变量名=条件表达式 ? 表达式1 : 表达式2;
条件表达式成立的时候执行表达式1,反之则执行2.
<3>重复型
(1)while(条件表达式) 循环体语句;
存在一次也不执行的情况
(2)do{
}while(条件表达式)
至少循环一次
(3)for(循环控制变量初始化语句;继续循环判断语句;修改控制循环变量语句)
1.3动态存储分配
在用C语言编写的程序中,经常使用函数malloc动态地为程序变量分配它所需要的空思并通过函数free 动态地释放这个圣间。函级maloe我行时,要余它的调用着使用困数sizeof 提供所需存储空间的数量,完成动态分配后还需要对返回指针做类型的强制转换。头文件在<malloc.h>中
//头文件在<malloc.h>中
char* s=(char *)malloc(128*sizeof(char));//内存动态分配
1.4逻辑和关系运算符运算的优先级
[-(非)、!]>[*,/,%]>[+,-]>[<,<=,>,>=]>[==,!=]>[&&]>[||]
2.算法和算法设计
2.1算法定义
为解决某一特定任务所设计的一个运算序列
2.2算法特性
1.输入性
2.输出性
3.确定性
4.有穷性
5.可行性
1.3算法设计的基本方法
(1)穷举法。也成为枚举,一一验证直到得到满足条件的值为止,否则问题无解。
举例:求a,b的最大公约数,采用枚举的方式来写就是
void prim(int a,int b){
int temp;
temp=(a>b)?a:b; //这里用到我们上面所讲到的条件赋值型语句
while(temp>0){
if(a%temp==0&&b%temp==0){ //找到一个数能同时被a,b整除
break;
temp--; // if不满足则执行自减运算
}
}
return (temp);
}
(2)迭代法。顾名思义通过不断更新得到最优解。
举个简单例子,迭代法求最大公约数
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
int maxgys(int a,int b); //函数原型声明(最大公因数)
printf("%d",maxgys(a,b));
return 0;
}
int maxgys(int a,int b)
{
while(b!=0)
{
int r;
r=a%b;
a=b;
b=r;
}
return a;
}
(3)递推法。通过前面的一些量推出最终结果,层层递进。
举个简单的例子,猴子吃桃问题。从后往前推,最后一天的一个桃子到倒数第二天的2*(sum+1)个桃子。
#include<stdio.h>
int main()
{
int sum,i;
sum=1;
for(i=10;i>1;i--)
sum=2*(sum+1);
printf("第一天桃子数为:%d\n",sum);
return 0;
}
(4)递归法。直接或者间接的调用它自身我们就称之为递归操作。
举个简单的例子,斐波那契数。Fib(1)=1,Fib(2)=1,此后每个数据元素的值都等于前两项之和。
#include<stdio.h>
int Fib(int n)
{
if (n <=2)
{
return 1;
}
else
{
return Fib(n - 1) + Fib(n - 2);//每一项都等于前两项之和
}
}
int main()
{
int n;
scanf("%d", &n);
printf("%d\n", Fib(n));
return 0;
}
————————————————新手小白的第二篇数据结构的博客,希望大家喜欢—————————————————————————————————