大数据结构与算法源代码.docx

上传人:b****5 文档编号:28054681 上传时间:2023-07-07 格式:DOCX 页数:215 大小:1.23MB
下载 相关 举报
大数据结构与算法源代码.docx_第1页
第1页 / 共215页
大数据结构与算法源代码.docx_第2页
第2页 / 共215页
大数据结构与算法源代码.docx_第3页
第3页 / 共215页
大数据结构与算法源代码.docx_第4页
第4页 / 共215页
大数据结构与算法源代码.docx_第5页
第5页 / 共215页
点击查看更多>>
下载资源
资源描述

大数据结构与算法源代码.docx

《大数据结构与算法源代码.docx》由会员分享,可在线阅读,更多相关《大数据结构与算法源代码.docx(215页珍藏版)》请在冰豆网上搜索。

大数据结构与算法源代码.docx

大数据结构与算法源代码

课程说明:

数据结构一共四天课程,day01~~~day04.

CSDDataStructureDAY01

1.基于顺序表的堆栈

2.基于链式表的堆栈

1基于顺序表的堆栈

栈是一种特殊的线性表,是限定在线性表表尾进行插入删除操作的线性表。

由栈的概念衍生出几个子概念,它们是:

1)栈顶,即允许进行插入、删除操作的一端,又称为表尾,用栈顶指针()来指示栈顶元素。

2)栈底,即固定端,又称为表头

3)空栈,即栈当中没有数据元素。

顺序栈是采用顺序存储结构的栈,即使用一组连续的存储单元(一般使用数组)来模拟栈,依次存放栈中的数据元素。

1.1方案

顺序栈的基本操作包括:

1)初始化操作,在初始化操作中将建立一个空栈。

2)判断栈空,判断栈中的数据元素个数是否为0。

3)入栈,在栈中加入一个数据元素。

4)出栈,在栈中删除一个数据元素。

5)取栈顶元素,将栈顶元素取出,但并不在栈中删除该元素。

1.2步骤

实现此案例需要按照如下步骤进行。

步骤一:

定义栈

在C语言中:

1)定义一个一维数组来表示栈的顺序存储空间。

2)定义一个变量来指出栈顶的位置。

3)这两方面的信息共同描述一个栈,可将它们用结构体封装在一起。

代码如下:

1.#defineLISTSIZE10

2.typedefintDataType;

3.structStack{

4.DataTypedata[LISTSIZE];

5.int;//除了记录大小还可以记录栈顶位置

6.};

上述代码中,以下代码:

1.#defineLISTSIZE100

是用一个宏常量来定义顺序表的容量,这样定义的好处是当需要修改顺序表的容量的时候,只需要修改该宏常量即可。

上述代码中,以下代码:

1.typedefintDataType;

是将数据类型int起了一个别名叫做DataType,并在后面的程序中只使用DataType,而不使用int。

这样做的好处是当堆栈中的数据类型发生变化时,只需要修改此句中的int为要改变的数据类型,即可将程序中所有数据变量的数据类型变成指定的类型。

步骤二:

初始化操作

在主程序中,定义栈结构体的变量。

在初始化函数中将该变量中的栈顶指针初始化为0,表示为空栈。

代码如下:

1.voidinit(structStack*stack)

2.{

3.stack->=0;

4.}

5.intmain(intargc,constchar*argv[])

6.{

7.structStackstack;

8.init(&stack);

9.}

步骤三:

判断栈空

判断栈空实际上是判断栈顶指针是否为0,因为当栈顶指针为0时,代表栈中没有数据元素。

代码如下:

1.boolempty(structStack*stack){

2.returnstack->==0;

3.}

步骤四:

入栈

入栈是在栈中加入一个数据元素,在入栈时,首先需要判断栈是否为满,如果栈满了,则就不能在向其中添加元素了,判断栈是否满的操作只有在顺序存储结构才会出现,因为采用顺序存储结构的栈是要事先定义栈的容量的。

然后将数据元素放入栈中,并使栈顶指针加1,指向下一个位置。

代码如下:

1.voidpush(structStack*stack,DataTyped){

2.if(stack->==LISTSIZE)

3.return;

4.stack->data[stack->++]=d;

5.}

上述代码中,以下代码:

1.if(stack->==LISTSIZE)

是判断栈是否满,判断栈顶指针是否与栈的容量相等,如果是,则表示栈已经满了。

步骤五:

出栈

出栈操作实际上是将栈中的栈顶元素删除,在出栈时,首先判断栈是否为空,如果栈为空则代表栈中已经没有数据元素了,此时是不可能进行出栈操作的。

然后,将栈顶指针减1。

代码如下:

1.voidpop(structStack*stack){

2.if(empty(stack))

3.return;

4.stack->--;

5.}

步骤六:

取栈顶元素

取栈顶元素操作实际上是仅返回栈顶元素,而栈顶指针并不变动。

在取栈顶元素时,首先也要判断栈是否为空,因为空栈同样是不可能有数据元素的。

代码如下:

1.DataTypeData(structStack*stack){

2.returnstack->data[stack->-1];

3.}

1.3完整代码

本案例的完整代码如下所示:

1.#include

2.#include

3.

4.#defineLISTSIZE10

5.typedefintDataType;

6.structStack{

7.DataTypedata[LISTSIZE];

8.int;//处了记录大小还可以记录栈顶位置

9.};

10.

11.voidinit(structStack*stack)

12.{

13.stack->=0;

14.}

15.

16.boolempty(structStack*stack){

17.returnstack->==0;

18.}

19.

20.voidpush(structStack*stack,DataTyped){

21.if(stack->==LISTSIZE)

22.return;

23.stack->data[stack->++]=d;

24.}

25.

26.voidpop(structStack*stack){

27.if(empty(stack))

28.return;

29.stack->--;

30.}

31.

32.DataTypeData(structStack*stack){

33.returnstack->data[stack->-1];

34.}

35.

36.

37.intmain()

38.{

39.structStackstack;

40.init(&stack);

41.push(&stack,30);

42.push(&stack,60);

43.push(&stack,80);

44.

45.while(!

empty(&stack)){

46.printf("%d",Data(&stack));

47.pop(&stack);

48.}

49.printf("\n");

50.

51.return0;

52.}

2基于链式表的堆栈

2.1问题

链栈是采用链式存储结构的栈,即使用一组不要求连续的存储空间来模拟栈。

每个栈元素为一个节点,每个节点中包含两个域,一个是数据域,用于存储栈元素的数据;另一个是指针域,用于存储下一个栈元素的地址。

2.2方案

链栈的基本操作包括:

1)初始化操作,在初始化操作中将栈顶指针置空。

2)判断栈空,判断栈顶指针是否为空。

3)入栈,在栈中加入一个数据元素。

4)出栈,在栈中删除一个数据元素。

5)取栈顶元素,将栈顶元素取出,但并不在栈中删除该元素。

2.3步骤

实现此案例需要按照如下步骤进行。

步骤一:

定义栈元素节点

在C语言中:

1)定义一个变量来表示栈元素的数据。

2)定义一个指针来指向下一个栈元素的位置。

3)这两方面的信息共同描述一个栈元素节点,可将它们用结构体封装在一起。

代码如下:

1.typedefintDataType;

2.structStack{

3.DataTypedata;

4.structStack*next;

5.};

上述代码中,以下代码:

1.structStack*next;

是定义了一个指向下一个栈元素的指针,由于下一个栈元素的数据类型与当前栈元素的数据类型相同,所以指针的数据类型就是栈节点的指针数据类型。

步骤二:

初始化操作

在主程序中,定义栈顶指针。

在初始化函数中将栈顶指针初始化为NULL,表示为空栈。

代码如下:

1.voidinit(structStack**)

2.{

3.*=NULL;

4.}

5.intmain()

6.{

7.structStack*;

8.init(&);

9.return0;

10.}

上述代码中,以下代码:

1.voidinit(structStack**)

定义了初始化函数的函数头,该函数有一个形参,是栈元素结构体指针的指针。

之所以使用指针的指针,是因为栈顶指针在函数执行过程中会被置空,而这种变化需要带回主函数。

步骤三:

判断栈空

判断栈空操作实际上就是判断栈顶指针是否为空。

代码如下所示:

1.boolempty(structStack*)

2.{

3.return==NULL;

4.}

步骤四:

入栈

入栈操作实际上就是在栈中加入一个数据元素,对于链栈,入栈操作本质上就是在栈中加入一个结点。

代码如下所示:

1.voidpush(structStack**,DataTyped)

2.{

3.structStack*newNode=(structStack*)malloc(sizeof(structStack));

4.newNode->data=d;

5.newNode->next=*;

6.*=newNode;

7.}

上述代码中,以下代码:

1.voidpush(structStack**,DataTyped)

定义了入栈函数的函数头,该函数有两个形参,第一个是栈结构的指针的指针,在这里使用指针的指针,还是因为需要将栈顶指针的变化带回主函数。

第二个形参是需要入栈的数据。

上述代码中,以下代码:

1.structStack*newNode=(structStack*)malloc(sizeof(structStack));

是构造一个新的栈元素节点。

上述代码中,以下代码:

1.newNode->data=d;

是将需要入栈的元素放入新的栈元素节点中。

上述代码中,以下代码:

1.newNode->next=*;

是将新创建的栈元素节点加入到栈中原栈顶元素的前面,成为新的栈顶元素。

上述代码中,以下代码:

1.*=newNode;

是栈顶指针指向新创建的栈顶元素。

正是由于这行代码,使栈顶指针发生了变化,而这种变化需要带回到主程序,所以函数的第一个形参必须是指针的指针。

步骤五:

出栈

出栈操作实际上就是从栈中删除栈顶位置的元素,对于链栈,出栈操作本质上就是在栈中删除一个结点。

代码如下所示:

1.voidpop(structStack**)

2.{

3.if(empty(*))

4.return;

5.structStack*tempNode=*;

6.*=(*)->next;

7.free(tempNode);

8.}

上述代码中,以下代码:

1.if(empty(*))

2.return;

是判断链栈是否为空,如果栈为空是不能从栈中删除元素的。

上述代码中,以下代码:

1.structStack*tempNode=*;

2.*=(*)->next;

3.free(tempNode);

首先用一个临时指针保存原栈顶指针指向的栈元素地址,即出栈元素的地址,然后将栈顶指针指向下一个元素,这样栈中就减少了一个元素。

最后释放临时指针指向的元素,即释放出栈元素所占的存储空间。

步骤六:

取栈顶元素

取栈顶元素实际上就是将栈顶元素的值返回,对于链栈,本质上是将栈顶节点的数据返回。

注意,在取栈顶元素时,首先要判断栈是否为空,空栈是没有数据元素的。

代码如下:

1.voidData(structStack*,DataType*data)

2.{

3.if(empty())

4.return;

5.*data=->data;

6.}

2.4完整代码

本案例的完整代码如下所示:

1.#include

2.#include

3.#include

4.

5.typedefintDataType;

6.structStack{

7.DataTypedata;

8.structStack*next;

9.};

10.

11.voidinit(structStack**)

12.{

13.*=NULL;

14.}

15.

16.boolempty(structStack*)

17.{

18.return==NULL;

19.}

20.

21.voidpush(structStack**,DataTyped)

22.{

23.structStack*newNode=(structStack*)malloc(sizeof(structStack));

24.newNode->data=d;

25.newNode->next=*;

26.*=newNode;

27.}

28.

29.voidpop(structStack**)

30.{

31.if(empty(*))

32.return;

33.structStack*tempNode=*;

34.*=(*)->next;

35.free(tempNode);

36.}

37.

38.voidData(structStack*,DataType*data)

39.{

40.if(empty())

41.return;

42.*data=->data;

43.}

44.

45.

46.intmain()

47.{

48.structStack*;

49.init(&);

50.push(&,30);

51.push(&,60);

52.push(&,80);

53.

54.while(!

empty()){

55.intdata;

56.Data(,&data);

57.printf("%d",data);

58.pop(&);

59.}

60.printf("\n");

61.

62.return0;

63.}

作业:

11.逆波兰法求解四则运算表达式

在计算机中,表达式的处理是很重要的一项工作。

表达式被分成中缀表达式和后缀表达式两种形式。

所谓中缀表达式就是我们日常书写表达式的方法,操作数在两边,运算符在中间,如1+2。

这种表达式易于理解,但是很难被计算机解析。

为了让计算机能够简单地解析表达式,可采用后缀表达式。

后缀表达式又被称为逆波兰表示法,是将运算符至于操作数的后面,如中缀表达式1+2表示成后缀表达式为12+。

后缀表达式中的一个特点是不需要使用括号,就可以准确地表示表达式的优先级,如中缀表达式1+2*3表示成后缀表达式后为123*-,而中缀表达式(1+2)*3表示成后缀表达式则为12+3*。

本案例的工作是先将中缀表达式转换成后缀表达式,然后计算后缀表达式。

参考答案

实现此案例需要按照如下步骤进行。

步骤一:

定义两个栈

首先,定义一个字符数组,用于存放待转换的字符串。

定义一个“结果栈”,用于存放转换过程中的每一步结果。

定义一个“运算符栈”,用于存放转换过程中的运算符。

代码如下所示:

1.#include

2.#include

3.

4.#defineLISTSIZE10

5.typedefintDataType;

6.

7.structStack{

8.DataTypedata[LISTSIZE];

9.int;//处了记录大小还可以记录栈顶位置

10.};

11.

12.voidinit(structStack*stack)

13.{

14.stack->=0;

15.}

16.

17.voidpush(structStack*stack,DataTyped){

18.stack->data[stack->++]=d;

19.}

20.

21.voidpop(structStack*stack){

22.stack->--;

23.}

24.

25.DataType(structStack*stack){

26.returnstack->data[stack->-1];

27.}

28.

29.boolempty(structStack*stack){

30.returnstack->==0;

31.}

32.

33.boolprior(charop1,charop2){

34.return(op1=='*'||op1=='/')&&(op2=='+'||op2=='-');

35.}

36.

37.intmain(){

38.charexpr[]="1+2*3/(4-1)";

39.structStackres;//结果栈

40.structStackoper;//运算符栈

41.init(&res);

42.init(&oper);

43.}

步骤二:

逐个读取字符串中的字符,直到结束

设置一个循环,逐个从字符数组expr中读取字符,直到遇见字符’\0’。

代码如下所示:

1.#include

2.#include

3.

4.#defineLISTSIZE10

5.typedefintDataType;

6.

7.structStack{

8.DataTypedata[LISTSIZE];

9.int;//处了记录大小还可以记录栈顶位置

10.};

11.

12.voidinit(structStack*stack)

13.{

14.stack->=0;

15.}

16.

17.voidpush(structStack*stack,DataTyped){

18.stack->data[stack->++]=d;

19.}

20.

21.voidpop(structStack*stack){

22.stack->--;

23.}

24.

25.DataType(structStack*stack){

26.returnstack->data[stack->-1];

27.}

28.

29.boolempty(structStack*stack){

30.returnstack->==0;

31.}

32.

33.boolprior(charop1,charop2){

34.return(op1=='*'||op1=='/')&&(op2=='+'||op2=='-');

35.}

36.

37.intmain(){

38.charexpr[]="1+2*3/(4-1)";

39.structStackres;//结果栈

40.structStackoper;//运算符栈

41.init(&res);

42.init(&oper);

43.

44.for(inti=0;expr[i]!

='\0';i++){

45.charch=expr[i];

46.}

47.}

步骤三:

将数字放入“结果栈”中

判断读出的字符是否是数字,如果是数字,则将该数字放入“结果栈”中。

代码如下所示:

1.#include

2.#include

3.

4.#defineLISTSIZE10

5.typedefintDataType;

6.

7.structStack{

8.DataTypedata[LISTSIZE];

9.int;//处了记录大小还可以记录栈顶位置

10.};

11.

12.voidinit(structStack*stack)

13.{

14.stack->=0;

15.}

16.

17.voidpush(structStack*stack,DataTyped){

18.stack->data[stack->++]=d;

19.}

20.

21.voidpop(structStack*stack){

22.stack->--;

23.}

24.

25.DataType(structStack*stack){

26.returnstack->data[stack->-1];

27.}

28.

29.boolempty(structStack*stack){

30.returnstack->==0;

31.}

32.

33.boolprior(charop1,charop2){

34.return(op1=='*'||op1=='/')&&(op2=='+'||op2=='-');

35.}

36.

37.intmain(){

38.charexpr[]="1+2*3/(4-1)";

39.structStackres;//结果栈

40.structStackoper;//运算符栈

41.init(&res);

42.init(&oper);

43.

44.for(inti=0;expr[i]!

='\0';i++){

45.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1