使用c语言描述数据结构以及算法的定义和设计

本文介绍了C语言中的数据类型,重点讨论了构造型(struct)、联合型(union)和指针型,并解释了typedef的作用。接着,阐述了算法的控制结构,包括顺序型、选择型和重复型,并探讨了动态存储分配。最后,通过实例讲解了穷举法、迭代法、递推法和递归法在算法设计中的应用。
摘要由CSDN通过智能技术生成

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;
}

————————————————新手小白的第二篇数据结构的博客,希望大家喜欢—————————————————————————————————

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java新手小白i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值