C语言 数据结构 学习

C语言 数据结构(20220323~?)

2022-0323 blog_12

数据结构介绍

什么是数据结构

数据结构,简单的理解就是数据的存储方式,主要是数据结构的定义和数据的操作方法。
常见的集中数据结构有:
线性表(顺序表、链表)、栈和队列、字符串、树存储,图存储等

如何衡量算法的好坏

线性表

什么是线性表

顺序表

顺序表的基本操作

单链表

单链表的基本操作

链表节点存储单个整型数据
代码文件简述

单链表的结构定义思路是借鉴B站海贼胡船长的教学视频,跟着敲代码,略做修改。
数据的基本操作:增删改查

头文件:DS01_linkTable.h
源文件:DS01_linkTable.c
主函数接口:DS01_linkTable_main();

#pragma once
#ifndef _DS01_LINK_TABLE_H_
#define _DS01_LINK_TABLE_H_


int DS01_linkTable_main();


#endif	// DS01_linkTable.h

源文件:DS01_linkTable.c

/*
	author :yxl
	teacher :Mr Hu in B station
	time :2022-3-25 23:49:58
*/

#include "DS01_linkTable.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>


typedef struct DS01_LinkNode
{
	int data;
	struct DS01_LinkNode* next;
}DS01_LinkNode;

typedef struct DS01_LinkTable
{
	DS01_LinkNode virtaulHeadNode;
	int length;
}DS01_LinkTable;



static DS01_LinkNode* InitLinkNode(int data)
{
	DS01_LinkNode* newNode = (DS01_LinkNode*)malloc(sizeof(DS01_LinkNode));
	if (NULL == newNode)
		return 0;
	memset(newNode, 0, sizeof(DS01_LinkNode));

	newNode->data = data;
	newNode->next = NULL;

	return newNode;
}

static DS01_LinkTable* InitLinkTable()
{
	DS01_LinkTable* newTable = (DS01_LinkTable*)malloc(sizeof(DS01_LinkTable));
	if (NULL == newTable)
		return NULL;
	memset(newTable, 0, sizeof(DS01_LinkTable));

	newTable->virtaulHeadNode.next = NULL;
	newTable->length = 0;

	return newTable;
}

static int ClearLinkNode(DS01_LinkNode* node)
{
	if (NULL == node)
		return -1;
	free(node);

	return 1;
}

static int ClearLinkTable(DS01_LinkTable* table)
{
	if (NULL == table)
		return -1;
	DS01_LinkNode* node_move = table->virtaulHeadNode.next;
	DS01_LinkNode* temp = NULL;
	int counter = 0;
	while (node_move)
	{
		temp = node_move->next;
		ClearLinkNode(node_move);
		node_move = temp;
		counter++;
	}
	printf("clear link table node counetr :%d, real length :%d \n", counter, table->length);
	free(table);

	return 1;
}

static int ShowLinkTable(DS01_LinkTable* table)
{
	if (NULL == table)
		return -1;
	printf("show link table, len :%d \n{\n", table->length);

	DS01_LinkNode* node_move = table->virtaulHeadNode.next;
	int counter = 0;
	while (node_move)
	{
		printf("\tconunter_%d:%d -> \n", counter, node_move->data);
		node_move = node_move->next;
		counter++;
	}
	printf("\tNULL \n} \n\n");

	return table->length;
}

static int InsertElement(DS01_LinkTable* table, int index, int data)
{
	if (NULL == table)
		return -1;
	if (0 > index || table->length < index)
		return -2;
	DS01_LinkNode* insertNode = InitLinkNode(data);
	if (NULL == insertNode)
		return -3;

	DS01_LinkNode* node_move = &(table->virtaulHeadNode);
	while (index--)
	{
		node_move = node_move->next;
	}
	insertNode->next = node_move->next;
	node_move->next = insertNode;
	table->length++;

	return table->length;
}

static int EraseElement(DS01_LinkTable* table, int index)
{
	if (NULL == table)
		return -1;
	if (0 > index || table->length <= index)
		return -2;
	DS01_LinkNode* node_move = &(table->virtaulHeadNode);
	DS01_LinkNode* temp = NULL;

	while (index--)
	{
		node_move = node_move->next;
	}
	temp = node_move->next->next;
	ClearLinkNode(node_move->next);
	node_move->next = temp;
	table->length--;

	return table->length;
}



int DS01_linkTable_main()
{
	printf("DS01_linkTable_main() \n");

    srand(time(0));
    DS01_LinkTable* table = InitLinkTable();
    if(NULL == table)
        return -1;
    
    int max_op = 20, op = 0, index = 0, data = 0;
    for(int i = 0; i < max_op; i++)
    {
        op = rand() % 4;
        index = rand() % (table->length + 1);
        data = rand() % 1000;
        switch(op)
        {
		case 0:
		case 1:
		case 2:
		{
			printf("insert %d at %d to link table, flag :%d \n", data, index, InsertElement(table, index, data));
		}break;
		case 3:
		{
			printf("erase element at %d from link table, flag :%d \n", index, EraseElement(table, index));
		}break;
        }
        ShowLinkTable(table);
    }
	ClearLinkTable(table);

	return 0;
}

代码运行结果

在这里插入图片描述

链表节点存储结构体数据
代码文件描述

头文件:DS02_linkTable_2.h
源文件:DS02_linkTable_2.c
主函数接口:DS02_linkTable_2_main()

#pragma once
#ifndef _DS02_LINK_TABLE_2_H_
#define _DS02_LINK_TABLE_2_H_


int DS02_linkTable_2_main();


#endif	// DS02_linkTable_2.h

/*
	author :yxl
	teacher :internet
	time :2022-3-26 23:35:53
*/


#include "DS02_linkTable_2.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>



typedef struct Book
{
	int bookId;
	char bookName[32];
}Book;

typedef struct DS02_LinkNode_2
{
	Book book;
	struct DS02_LinkNode_2* next;
}DS02_LinkNode_2;

typedef struct DS02_LinkTable_2
{
	DS02_LinkNode_2 virtualHead;
	int length;
}DS02_LinkTable_2;



static DS02_LinkNode_2* InitLinkNode(Book book)
{
	DS02_LinkNode_2* newNode = (DS02_LinkNode_2*)malloc(sizeof(DS02_LinkNode_2));
	if (NULL == newNode)
		return NULL;
	memset(newNode, 0, sizeof(DS02_LinkNode_2));

	newNode->book.bookId = book.bookId;
	memcpy(newNode->book.bookName, book.bookName, sizeof(newNode->book.bookName));
	newNode->next = NULL;

	return newNode;
}

static DS02_LinkTable_2* InitLinkTable()
{
	DS02_LinkTable_2* newTable = (DS02_LinkTable_2*)malloc(sizeof(DS02_LinkTable_2));
	if (NULL == newTable)
		return NULL;
	memset(newTable, 0, sizeof(DS02_LinkTable_2));

	newTable->virtualHead.next = NULL;
	newTable->length = 0;

	return newTable;
}

static int ClearLinkNode(DS02_LinkNode_2* node)
{
	if (NULL == node)
		return -1;
	free(node);

	return 1;
}

static int ClearLinkTable(DS02_LinkTable_2* table)
{
	if (NULL == table)
		return -1;
	DS02_LinkNode_2* node = table->virtualHead.next;
	DS02_LinkNode_2* temp = NULL;
	while (node)
	{
		temp = node->next;
		ClearLinkNode(node);
		node = temp;
	}
	free(table);

	return 1;
}

static int ShowLinkTable(DS02_LinkTable_2* table)
{
	if (NULL == table)
		return -1;
	printf("show link table, length :%d \n{\n", table->length);
	DS02_LinkNode_2* node = table->virtualHead.next;
	int counter = 0;
	while (node)
	{
		printf("\tcounter :%d, %d, %s -> \n", counter, node->book.bookId, node->book.bookName);
		node = node->next;
		counter++;
	}
	printf("\tNULL \n}\n\n");

	return table->length;
}

static int InsertElement(DS02_LinkTable_2* table, int index, Book book)
{
	if (NULL == table)
		return -1;
	if (0 > index || table->length < index)
		return -2;
	DS02_LinkNode_2* insertNode = InitLinkNode(book);
	if (NULL == insertNode)
		return -3;
	DS02_LinkNode_2* temp = &(table->virtualHead);

	while (index--)
	{
		temp = temp->next;
	}

	insertNode->next = temp->next;
	temp->next = insertNode;
	table->length++;

	return table->length;
}

static int EraseElement(DS02_LinkTable_2* table, int index)
{
	if (NULL == table)
		return -1;
	if (0 > index || table->length <= index)
		return -2;
	DS02_LinkNode_2* node = &(table->virtualHead);
	DS02_LinkNode_2* temp = NULL;
	
	while(index--)
	{
		node = node->next;
	}

	temp = node->next->next;
	ClearLinkNode(node->next);
	node->next = temp;
	table->length--;

	return table->length;
}



int DS02_linkTable_2_main()
{
	printf("DS02_linkTable_2_main() \n");

	srand(time(0));
	int max_op = 20, op = 0, index = 0;

	DS02_LinkTable_2* table = InitLinkTable();
	Book book = {123, "book_name"};

	for (int i = 0; i < max_op; i++)
	{
		op = rand() % 4;
		index = rand() % (table->length + 1);
		book.bookId = i + 1000;
		sprintf(book.bookName, "book_name_%d", book.bookId);

		switch (op)
		{
		case 0:
		case 1:
		case 2:
		{
			printf("insert (%d, %s) at %d to link table, flag :%d \n", 
				book.bookId, book.bookName, index, InsertElement(table, index, book));
		}break;
		case 3:
		{
			printf("erase element at %d from table, flag :%d \n", 
				index, EraseElement(table, index));
		}break;
		default :
			break;
		}
		ShowLinkTable(table);
	}
	ClearLinkTable(table);

	return 0;
}

代码运行结果

在这里插入图片描述

双向链表

双向链表的基本操作

栈和队列

什么是栈

顺序栈及基本操作

什么是队列

顺序队列及基本操作

队列存储单个整型数据
代码文件描述

头文件:DS03_queue.h
源文件:DS03_queue.c
主函数接口:DS03_queue_main()

#pragma once
#ifndef _DS03_QUEUE_H_
#define _DS03_QUEUE_H_


int DS03_queue_main();


#endif	// DS03_queue.h

/*
	author :yxl
	teacher :Mr Hu in B station
	time :2022-3-30 21:41:18
*/

#include "DS03_queue.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>



const int QueueMaxLength = 20;
typedef struct tQueue
{
	int* iData;
	int head;
	int tail;
}tQueue;


static tQueue* InitQueue()
{
	tQueue* newQueue = (tQueue*)malloc(sizeof(tQueue));
	if (NULL == newQueue)
		return NULL;
	memset(newQueue, 0, sizeof(tQueue));

	newQueue->iData = (int*)malloc(sizeof(int) * QueueMaxLength);
	memset(newQueue->iData, 0, sizeof(int) * QueueMaxLength);

	newQueue->head = 0;
	newQueue->tail = 0;

	return newQueue;
}

static int ClearQueue(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	if (NULL == queue->iData)
		return -2;
	free(queue->iData);
	printf("clear queue, real len :%d, max len :%d \n", (queue->tail - queue->head + QueueMaxLength) % QueueMaxLength, QueueMaxLength);
	free(queue);

	return 1;
}

static int GetQueueLength(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	return (queue->tail - queue->head + QueueMaxLength) % QueueMaxLength;
}

static int IsEmpty(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	if (queue->tail == queue->head)
		return 1;

	return 0;
}

static int IsFull(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	if (queue->head == (queue->tail + 1) % QueueMaxLength)
		return 1;

	return 0;
}

static int ShowQueue(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	printf("show queue, real len :%d \n{ ", GetQueueLength(queue));
	int i = queue->head;
	int counter = 0;
	while (queue->tail != i)
	{
		printf("(%d:%d), ", counter, queue->iData[i]);
		i = (i + 1) % QueueMaxLength;
		counter++;
	}
	printf("}\n\n");

	return GetQueueLength(queue);
}

static int EnterQueue(tQueue* queue, int data)
{
	if (NULL == queue)
		return -1;
	if (1 == IsFull(queue))
	{
		printf("queue is full, will set 0 \n");
		queue->head = queue->tail = 0;
	}

	queue->iData[queue->tail] = data;
	queue->tail = (queue->tail + 1) % QueueMaxLength;

	return GetQueueLength(queue);
}

static int OutQueue(tQueue* queue)
{
	if (NULL == queue)
		return -1;
	if (1 == IsEmpty(queue))
	{
		printf("queue is empty \n");
		return -2;
	}
	int out = queue->iData[queue->head];
	queue->head = (queue->head + 1) % QueueMaxLength;

	return out;
}



int DS03_queue_main()
{
	printf("DS03_queue_main()\n ");

	srand(time(0));
	tQueue* queue = InitQueue();
	int max_op = 50, op = 0, data = 0;

	for (int i = 0; i < max_op; i++)
	{
		op = rand() % 4;
		data = rand() % 1000;
		switch (op)
		{
		case 0:
		case 1:
		case 2:
		{
			printf("enter %d to queue, len :%d, flag :%d \n", data, GetQueueLength(queue), EnterQueue(queue, data));
		}break;
		case 3:
		{
			printf("out queue len :%d, element :%d \n", GetQueueLength(queue), OutQueue(queue));
		}break;
		default :
			break;
		}
		ShowQueue(queue);
	}
	ClearQueue(queue);

	return 0;
}

代码运行结果

![(https://img-blog.csdnimg.cn/39f071172f6040e4ae3fa5c154ac97f9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oyH6Im6,size_20,color_FFFFFF,t_70,g_se,x_16)

链式队列及基本操作

字符串

什么是串

字符串操作总结

树与二叉树

二叉树代码演示

参考资料说明

**本篇文章内容属于作者在网上查找的一些资料总结,以及跟着教程写的代码和笔记;仅供学习和参考,如有侵权,请及时联系本人沟通处理;如需转载,请注明出处;内容持续填补中,请大家多多指教;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值