title: C语言链表的实现
date: 2021-07-26 20:13:53
tags: c语言、链表
本文实现了数据结构中链表的c语言表达,本且尝试创建一个完整文件而非单一的.c文件。使用的IDE是VS2019,作为c语言的初学者,许多地方做的不够完善还请海涵。在代码过程中遇到的问题与解答已附在代码中。个人博客:https://guotianyu-2020.github.io,欢迎关注。
1.文件之间的“沟通”
设置main.c文件作为主文件,single dir.c存放链表的各种函数,head.h是头文件。在main文件中要在开头调用head文件。格式:#include"head.h"。在head文件里主要存放定义好的结构体,函数声明。在存放函数的single dir文件中也要开头调用head文件。
2.代码部分
所有函数只接受头指针。
结构体定义:
typedef struct {
char name[20];
int price;
int order;
}BookInf;
typedef struct node{
BookInf Book;
struct node* next;
}Node;
主函数部分:通过useall函数(位于single dir文件)作为一个接口,执行功能函数内容在useall里。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"head.h"
int main() {
Node* SDHead = (Node*)malloc(sizeof(Node));
if (SDHead)
{
UseAll_SD(SDHead);
}
return 0;
}
功能函数部分(写代码过程中的问题已经放到注释里面了):
#include"head.h"
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
static int n; //This n is to record times Add() is called so as to pass the order to p->Book.order.
void Initialize(Node* head) //If you want to keep this function running in main.c, use extern for its return object
{ //The function Initalize change the value of the pointer
strcpy_s(head->Book.name, 20, " ");
head->Book.price = 0; //Node head's data is empty.
head->Book.order = 0;
head->next = NULL;
}
void Add(Node* head)
{
char receive_name[20];
int receive_price;
Node* last = head;
Node* p = (Node*)malloc(sizeof(Node));
int i;
if (last && p) {
p->Book.order = 1;
printf("Please input the book name:\n");
gets_s(receive_name, 20);
setvbuf(stdin, NULL, _IOFBF, 512); //setvbuf is a function that clears the buffers.
printf("Please input the price of te book:\n");
scanf_s("%d", &receive_price);
setvbuf(stdin, NULL, _IOFBF, 512);
n += p->Book.order;
p->Book.order = n;
for (i = 0; i <= 19; i++) {
p->Book.name[i] = receive_name[i]; //Both Book.name and receive_name are strings defined by arrays, use for loop to copy.
}
p->Book.price = receive_price;
p->next = NULL;
if (last) { //At the beginning, last points to head. Head's next area is NULL.
while (last->next) {
last = last->next; //To find the real last one.
}
last->next = p;
}
else {
head->next = p;
}
printf("The last book is: %s\n", p->Book.name);
printf("The price of the book is: %d\n", p->Book.price);
printf("The order of the book is: %d\n", p->Book.order);
}
}
void ShowList(Node* head)
{
Node* pointer1 = head->next;
do
{
if (pointer1) {
printf("Current information:\n");
printf("Book name: %s Price: %d Order: %d\n", pointer1->Book.name, pointer1->Book.price, pointer1->Book.order);
pointer1 = pointer1->next;
}
else
{
printf("ERROR!");
}
} while (pointer1);
}
void ListEmpty(Node* head)
{
if (head->next)
{
printf("The list is not empty.\n");
}
else
{
printf("The list is empty.\n");
}
}
void DestoryList(Node* head)
{
Node* p;
while (head)
{
p = head;
head = head->next;
free(p);
}
printf("The linked list is destoryed./n");
}
void ClearList(Node* head)
{
Node* p, * q;
p = head->next;
while (p)
{
q = p->next;
free(p);
p = q;
}
printf("The linked list is cleared./n");
head->next = NULL;
}
void ListLength(void)
{
printf("The current length is %d\n", n);
}
void GetElem(Node* head)
{
int i, j = 0;
Node* p = head;
printf("Input the position you want to search:\n");
scanf_s("%d", &i);
do
{
p = p->next;
j++;
}while (i != j && p);
if (p)
{
printf("The book at position %d is %s\n", i, p->Book.name);
printf("The price is %d\n", p->Book.price);
}
}
void LocateElem(Node* head)
{
Node* p = head;
char r_name[20];
int i = 0;
printf("Input the book name:\n");
gets_s(r_name, 20);
while (p)
{
if (strcmp(p->Book.name, r_name) == 0)
{
printf("The book you are searching for is at the position %d\n", i);
break;
}
if (p->next == NULL && strcmp(p->Book.name, r_name) != 0)
{
printf("Book %s is not found.", r_name);
}
i++;
p = p->next;
}
}
void Insert(Node* head)
{
int i, j, k = 1;
int l = 0;
char r_name[20];
Node* p = head;
Node* new = (Node*)malloc(sizeof(Node));
if (new)
{
printf("Input the position you want to insert:\n");
scanf_s("%d", &i);
setvbuf(stdin, NULL, _IOFBF, 512);
printf("Input book name:\n");
gets_s(r_name, 20);
setvbuf(stdin, NULL, _IOFBF, 512);
printf("Input the price of the book:\n");
scanf_s("%d", &j);
setvbuf(stdin, NULL, _IOFBF, 512);
for (l = 0; l <= 19; l++)
{
new->Book.name[l] = r_name[l];
}
new->Book.order = i;
new->Book.price = j;
while (p && k < i) // Find the position i - 1
{
p = p->next;
k++;
}
if (p)
{
new->next = p->next;
p->next = new; //Q1: Why this line changes the content of linked list.
p = p->next->next; //Q1: Why this line changes the content of linked list.
}
while (p)
{
p->Book.order++;
p = p->next;
}
}
}
void ElemDelete(Node* head)
{
Node* p = head;
Node* q;
int i, j = 0;
printf("Input the posiotion you want to delete:");
scanf_s("%d", &i);
do
{
p = p->next;
j++;
} while ((i - 1) != j && p);
if (p)
{
q = p->next;
p->next = q->next;
p->next->Book.order -= 1;
free(q);
}
}
void UseAll_SD(Node* head)
{
Initialize(head);
Add(head);
Add(head);
Add(head);
ShowList(head);
Insert(head);
ShowList(head);
ElemDelete(head);
ShowList(head);
GetElem(head);
ClearList(head);
ShowList(head);
}
头文件:
#ifndef _Initialize_H_
#ifndef _Add_H_
#define _Initialize_H_
#define _Add_H_
typedef struct {
char name[20];
int price;
int order;
}BookInf;
typedef struct node{
BookInf Book;
struct node* next;
}Node;
void Initialize(Node* head);
void Add(Node* head);
void ShowList(Node* head);
void ListEmpty(Node* head);
void DestoryList(Node* head);
void ClearList(Node* head);
void ListLength(head);
void GetElem(Node* head);
void LocateElem(Node* head);
void Insert(Node* head);
void ElemDelete(Node* head);
void UseAll_SD(Node* head);
#endif
#endif
3.反思与改进
1.对于extern的使用方法不明确,一开始以为必须加,但是发现不加也没什么影响。
2.对于初始化函数的执行很模糊。经提问得知main函数里必须直接分配空间,局部变量才在内部分配。一般的数据结构不需要人为分配,比如整数,但是像结构体指针这样的就需要。