使用C语言实现栈

说明

  • 作为栈顶的节点不存储数据

使用C语言实现链表

第一步:定义相应结构

由于实现链表的编程语言为C,不能够使用类,故使用结构来实现链表中的节点;

1
2
3
4
5
typedef struct LinkList {
char name[MAX_INPUT];
long number;
LinkList* next;
}Link;

该结构由一个字符数组,一项编号和一个指向此结构的指针组成。

第二步:定义输入函数

为了更容易、更准确的获取输入,在程序中重新定义输入函数,在原有fgets()函数的基础上略作修改,得到新的输入函数s_gets();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
char* s_gets(char* st, int n) {
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n') {
continue;
}
}
}
return ret_val;
}

该函数为返回类型为字符指针、接受参数为一个字符指针和一个整数的输入函数,其中字符指针就是字符数组名称,因为数组名称本质上就是数组首元素的地址,而该数组为字符数组,故该字符数组名称本质上就是字符指针;

在函数内部,我声明了两个字符指针,一个用来接受fgets函数的返回值,一个用来接受查找字符函数(strchr)的返回值;

关于fgets()函数:

  • 如果接受输入的字符数量超过字符数组的大小(MAX_INPUT),fgets()函数会返回先前传入的地址,即字符数组的名称,并且把末尾的字符换为空字符('\0'),使之成为一个字符串;
  • 如果接收输入的字符数量在字符数组的大小以内,那么fgets()函数会将空字符放置在换行符之前,然后同样返回先前传入的地址;
  • 需要注意的是:fgets()函数在遇到文件结尾(EOF End Of File)时将会返回一个空指针;

关于strchr()函数:

  • 在某个字符数组中查找某字符,并返回指向该字符的指针
  • r如果字符串中不包含该字符,则返回一个空指针

经过重写,修改如下:

首先使用fgets()函数接收输入,并将返回值存储在指针ret_val中,然后对该指针进行判断,如果不为空指针,则使用字符查找函数查找换行符,并将该换行符替换为空字符,如果查找换行符失败,说明输入的字符数量超过了字符数组的大小,这时使用一个while循环接收其余的输入并抛弃;如果ret_val为空指针,说明遇到文件结尾;最后返回ret_val;

第三步:编写主函数进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int main() {
char input[MAX_INPUT];
Link* p = (Link*)malloc(sizeof(Link*));
Link* temp = p;
printf("Now start recording: \n");
printf("Name : ");
while (s_gets(input,MAX_INPUT) != NULL && input[0] != '\0') {
Link* a = (Link*)malloc(sizeof(Link));
a->next = NULL;
temp->next = a;
temp = temp->next;
strcpy(a->name, input);
printf("Number: ");
scanf("%ld", &(a->number));
getchar();
printf("Name : ");
}
temp = p->next;
printf("Recorded Data: \n");
while (temp) {
printf("Name: %s\tNumber: %ld\n", temp->name, temp->number);
temp = temp->next;
}
return 0;
}
  • 首先声明一个字符数组用来储存输入,然后声明一个节点类型的指针作为头节点,并为其分配内存,接着再声明一个同样的临时指针指向该头指针,这里使用临时指针的目的是作为当前指针与下一个指针的过渡指针,同时保持头指针指向的内容不变,方便最后的输出;
  • 在输出提示信息之后进入循环,退出条件为输入空行;在循环中,首先声明指向当前节点的指针并为其分配内存,接着将该指针指向的结构中的指针声明为NULL,然后将当前节点的指针赋给临时指针指向的结构的指针,使其与上一个节点相连,然后再将临时指针指向的指针赋给自身(其实就相当于使临时指针指向下一个节点);接着将刚刚接收的输入复制到当前节点的name变量中,然后再接收编号的输入并存储到当前节点的number变量中;值得注意的是,在使用scanf()函数接收输入后该函数似乎会将换行符留在缓存区中,所以这里需要使用getchar()函数来将该换行符从缓存区中去除;
  • 在循环结束之后,我将临时指针指向了头节点的下一个节点(请注意,头节点中并没有储存除下一个节点的地址之外的任何信息,故此处从头节点的下一个节点开始);然后进入下一个while循环,退出条件为临时指针为空指针(因为在上一个while循环中已经将当前节点中的指针声明为NULL了,所以一旦第一个循环结束,最后一个节点中的指针必为NULL),然后打印出当前节点的信息并将临时指针指向下一个节点。

源代码

最后附上源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define MAX_INPUT 20

char* s_gets(char* st, int n);

char* s_gets(char* st, int n) {
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val) {
find = strchr(st, '\n');
if (find) {
*find = '\0';
}
else {
while (getchar() != '\n') {
continue;
}
}
}
return ret_val;
}

typedef struct LinkList {
char name[MAX_INPUT];
long number;
LinkList* next;
}Link;

int main() {
char input[MAX_INPUT];
Link* p = (Link*)malloc(sizeof(Link*));
Link* temp = p;
printf("Now start recording: \n");
printf("Name : ");
while (s_gets(input,MAX_INPUT) != NULL && input[0] != '\0') {
Link* a = (Link*)malloc(sizeof(Link));
a->next = NULL;
temp->next = a;
temp = temp->next;
strcpy(a->name, input);
printf("Number: ");
scanf("%ld", &(a->number));
getchar();
printf("Name : ");
}
temp = p->next;
printf("Recorded Data: \n");
while (temp) {
printf("Name: %s\tNumber: %ld\n", temp->name, temp->number);
temp = temp->next;
}
return 0;
}

人工智能入门-查找

概述

众所周知,人工智能在近些年十分火爆,在各个领域的应用也是十分广泛,其中一个领域就是导航。