C语言链表的实现


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函数里必须直接分配空间,局部变量才在内部分配。一般的数据结构不需要人为分配,比如整数,但是像结构体指针这样的就需要。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值