数据结构与算法

Posted 子羽丿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构与算法相关的知识,希望对你有一定的参考价值。

统一声明:
博客转载 声 明 : 本博客部分内容来源于网络、书籍、及各类手册。
        内容宗旨为方便查询、总结备份、开源分享。
        部分转载内容均有注明出处,如有侵权请联系博客告知并删除,谢谢!

百度云盘提取码:统一提取码: ziyu

一、基本概念

1.1、数据结构起源

由于最初涉及的运算对象是简单的整型、实型或布尔型数据,所以程序设计者的主要精力集中于程序设计的技巧上,而无需重视数据结构。随着计算机应用领域的扩大和软硬件的发展,非数值计算问题显得越来越重要。

据统计,当今处理非数值计算问题占用了90%以上的机器时间。
这类问题涉及的数据结构更为复杂,数据元素之间的相互关系一般无法用数学方程式加以描述。因此,解决这类问题的关键不再是数学分析和计算方法,而是要设计出合适的数据结构。

所以,数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。

1968年,美国DonaldEKnuth教授在其所写的《计算机程序艺术》第一卷《基本算法》中,较系统地阐述了数据的逻辑结构和存储结构以及操作,开创了“数据结构”的课程体系。同年,数据结构作为一门独立课程,在计算机科学学位课程中开始出现。

数据结构是介于数学、计算机硬件、计算机软件、逻辑学等学科之间的综合学科,是计算机学科的一门核心课程,是设计实现编译系统、操作系统、数据库等其他课程和大型应用程序的基础。

进入70年代,出现了大型计算机程序,软件开始相对独立,结构程序设计成为程序设计方法学的主要内容。

程序设计的实质是对实际问题设计/选择好的数据结构和好的算法,
而好的算法在很大程度上取决于描述实际问题的数据结构。

著名的瑞士计算机科学家沃思(N.Wirth)教授曾提出:
程序设计 = 数据结构 + 算法

1.2、数据结构


1.3、数据结构基本概念

正所谓“巧妇难为无米之炊”,数据结构是针对数据进行研究的学科,那么这里的“米”就是数据。

数据不仅仅包含整型、字符型、浮点型等数值类型,还包括字符、图像、声音、视频等非数值类型。

数据元素:例如,若我们要对家畜类进行调查,则牛、羊、马、狗、猪等都是家畜类的数据元素。
数据项: 例如,人这样的数据元素,可以有眼、耳、鼻、口、手等数据项,也可以有姓名、年龄、性别、出生日期、出生地址、联系电话等数据项。具体使用哪些数据项,要视你做的程序决定。

  • 数据:描述客观事实的符号,能被计算机所识别、操作,并输入到计算机中的一些符号的集合,信息的载体
  • 数据项:一个数据元素可由若干数据项组成,构成数据元素的最小单位
  • 数据元素:数据基本单位,通常作为一个整体考虑和处理
  • 数据结构:相互之间存在一种或多种特定关系的数据元素的结合

1.4、数据结构三要素

1.4.1. 逻辑结构: 线性、树形、图状

1.4.2. 存储结构:顺序存储、链式存储

1.4.3. 数据的运算:增删改查

1.5、数据结构三个方面

二、线性表(逻辑结构)

2.1、线性表的概念

线性表的顺序存储结构,指的是用一段地址连续的存储单元依次存储线性表的数据元素。
线性结构:一对一

假设有n个数据元素,满足线性结构;
特点:1.n = 0, 该表为空
   2.a0为表头,没有直接前驱, a(n-1),表尾,没有直接后继
   3.其他有且仅有一个直接前驱和一个直接后继

顺序存储结构存放线性表:顺序表
链式存储结构存放线性表:链表

2.2、顺序表

2.2.1、顺序表运算:
顺序表初始化:
  typedef struct list{
    int data[size];
    int last;
  }seqlist;

2.2.2、静态分配:
如果“数组”放满怎么办?
如果刚开始就声明一个内存空间呢?

2.2.3、动态分配:
int *p = (int *)malloc(3 * sizeof(int));

2.2.4、顺序表的基本运算:
初始化
判空
判满
求表长
插入
删除
查找
修改
清空
销毁
输出

2.2.5、顺序表的实现
(1)seqlist_malooc.c

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

#define SIZE 100

typedef int data_t;		//重命名int 类型

//顺序表
typedef struct list{
	data_t data[SIZE];	//数组,用来存放数据元素
	int last;		//最后一个元素下标
}seqlist;			//重命名,struct list == seqlist,结构体的数据类型

//初始化
seqlist *creatSeqlist()
{
	//动态分配
	seqlist *seq = (seqlist *)malloc(sizeof(seqlist));//结构体指针
	if(seq == NULL)
	{
		printf("malloc failed!\\n");
		return NULL;
	}

	memset(seq->data, 0, sizeof(seq->data));//把结构体的成员data数组清零
	seq->last = -1;	//如果下标为-1,说明顺序表中没有元素存在

	return seq;
}

//判空
int seqlist_is_empty(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return ((seq->last == -1)?1:0);
}

//判满
int seqlist_is_full(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return ((seq->last+1 == SIZE)?1:0);
}

//求表长
int seqlist_length(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return (seq->last+1);
}

//插入:按位置插入数据元素
int inserSeqlistByPos(seqlist *seq, int pos, data_t data)
{
	if(NULL == seq)			//malloc是否成功
		return -1;

	if(seqlist_is_full(seq) == 1)	//判满
		return -1;

	int len = seqlist_length(seq);	//插入的位置
	if(pos < 0 || pos > len)
		return -1;

	int i = 0;
	for(i= seq->last; i>=pos; i--)
	{
		seq->data[i+1] = seq->data[i];
	}
	seq->data[pos] = data;
	seq->last++;
}

//删除:按位置删除数据元素
int deleteSeqlistByPos(seqlist *seq, int pos)
{
	if(NULL == seq)
		return -1;

	if(seqlist_is_empty(seq) == 1)	//判空
		return -1;

	int len = seqlist_length(seq);
	if(pos < 0 || pos > seq->last)
		return -1;

	int i = 0;

	for(i=pos; i<seq->last; i++)
	{
		seq->data[i] = seq->data[i+1];
	}
	seq->last--;
}

//查找:按位置来查找数据元素
data_t findSeqlistByPos(seqlist * seq, int pos)
{
	if(NULL == seq)
		return -1;
	if(seqlist_is_empty(seq) == 1)
	return -1;

	int len = seqlist_length(seq);
	if(pos < 0 || pos > seq->last)
		return -1;

	return seq->data[pos];
}

//修改:按位置来修改数据元素
int changSeqlisByPos(seqlist *seq, int pos, data_t data)
{
	if(NULL == seq)
		return -1;
	if(seqlist_is_empty(seq) == 1)
	return -1;

	int len = seqlist_length(seq);
	if(pos < 0 || pos > seq->last)
		return -1;
	
	seq->data[pos] = data;	//按位置来修改数据元素
}

//查找:按值来查找数据元素,返回那个值的下标
int findSeqlistByData(seqlist *seq, data_t data)
{
	if(NULL == seq)
		return -1;
	if(seqlist_is_empty(seq) == 1)
		return -1;
	
	int i = 0;
	for(i=0; i<=seq->last; i++)
	{
		if(seq->data[i] == data)
		{
			return i;
		}
	}
}

//删除:按值来删除数据元素
int deleteSeqlistByData(seqlist *seq, data_t data)
{
	int pos = findSeqlistByData(seq, data);

	deleteSeqlistByPos(seq, pos);
}

//修改:按值来修改数据元素
int changeSeqlistByData(seqlist *seq, data_t old_data, data_t new_data)
{
	int pos = findSeqlistByData(seq, old_data);

	changSeqlisByPos(seq, pos, new_data);
}

//清空
void clearSeqlist(seqlist *seq)
{
	if(NULL == seq)
		return;

	seq->last = -1;
}

//销毁:把地址的地址回收掉
void destroySeqlist(seqlist **seq)
{
	free(*seq);

	*seq = NULL;
}

//输出
void displaySeqlist(seqlist *seq)
{
	if(NULL == seq)
		return;

	if(seqlist_is_empty(seq) == 1)
		return ;
	
	int i = 0;
	for(i=0; i<=seq->last; i++)
	{
		printf("%d ", seq->data[i]);
	}

	puts(" ");
}

int main(int argc, const char *argv[])
{
	seqlist *seq = creatSeqlist();
	if(seq == NULL)
	{
		printf("malloc failed!\\n");
		return -1;
	}

	int n = seqlist_is_empty(seq);
	printf("line:%d, n:%d\\n",__LINE__, n);			//:line:221, n:1

	int m = seqlist_is_full(seq);
	printf("line:%d, m:%d\\n",__LINE__, m);			//:line:224, n:0

	int len = seqlist_length(seq);
	printf("line:%d, n:%d\\n",__LINE__, len);		//:line:227, n:0

	//按位置插入数据元素
	int i = 0;
	while(i<10)
	{
		inserSeqlistByPos(seq, i, i+1);			
		i++;
	}
	len = seqlist_length(seq);
	printf("line:%d, n:%d\\n",__LINE__, len);		//: 10
	//打印输出
	displaySeqlist(seq);							//:1 2 3 4 5 6 7 8 9 10 

	//按位置删除
	deleteSeqlistByPos(seq, 2);
	//打印输出
	displaySeqlist(seq);							//:1 2 4 5 6 7 8 9 10 

	//按位置来查找数据元素
	data_t data = findSeqlistByPos(seq, 5);
	printf("data = %d\\n", data);					//:data = 7

	//按位置来修改数据元素
	changSeqlisByPos(seq, 1, 250);
	//打印yy输出
	displaySeqlist(seq);							//:1 250 4 5 6 7 8 9 10

	//查找:按值来查找数据元素,返回那个值的下标
	int pos = findSeqlistByData(seq, 250);
	printf("line:%d, pos = %d\\n", __LINE__, pos);	//:line:257, pos = 1

	//删除:按值来删除数据元素
	deleteSeqlistByData(seq, 7);
	displaySeqlist(seq);							//:1 250 4 5 6 8 9 10

	//修改:按值来修改数据元素
	changeSeqlistByData(seq, 10, 100);
	displaySeqlist(seq);							//:1 250 4 5 6 8 9 100

	//清空
	clearSeqlist(seq);
	displaySeqlist(seq);							//:
	len = seqlist_length(seq);
	printf("line:%d, n:%d\\n",__LINE__, len);		//:line:271, n:0

	//销毁
	destroySeqlist(&seq);
	printf("seq = %p\\n", seq);						//:seq = (nil)

	return 0;
}										

(2)seqlist_static.c

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

#define SIZE 100

typedef int data_t;		//重命名int 类型

//顺序表
typedef struct list{
	data_t data[SIZE];	//数组,用来存放数据元素
	int last;		//最后一个元素下标
}seqlist;			//重命名,struct list == seqlist,结构体的数据类型

//判空
int seqlist_is_empty(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return ((seq->last == -1)?1:0);
}

//判满
int seqlist_is_full(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return ((seq->last+1 == SIZE)?1:0);
}

//求表长
int seqlist_length(seqlist *seq)
{
	if(seq == NULL)
		return -1;
	return (seq->last+1);
}

//插入:按位置插入数据元素
int inserSeqlistByPos(seqlist *seq, int pos, data_t data)
{
	if(NULL == seq)			//malloc是否成功
		return -1;

	if(seqlist_is_full(seq) == 1)	//判满
		return -1;

	int len = seqlist_length(seq);	//插入的位置
	if(pos < 0 || pos > len)
		return -1;

	int i = 0;
	for(i= seq->last; i>=pos; i--)
	{
		seq->data[i+1] = seq->data[i];
	}
	seq->data[pos] = data;
	seq->last++;
}

//插入:按位置插入数据元素
int deleteSeqlistByPos(seqlist *seq, int pos)
{
	if(NULL == seq)
		return -1;

	if(seqlist_is_empty(seq) == 1)	//判空
		return -1;

	int len = seqlist_length(seq);
	if(pos < 0 || pos > seq->last)
		return -1;

	int i = 0;

	for(i=pos; i<seq->last; i++)
	{
		seq->data[i] = seq->data[i+1];
	}
	seq->last--;
}

//查找:按位置来查找数据元素
data_t findSeqlistByPos(seqlist * seq, int pos)
{
	if(NULL == seq)
		return -1;
	if(seqlist_is_empty(seq) == 1)
	return -1;

	int len = seqlist_length(seq);
	if(pos < 0 || pos 以上是关于数据结构与算法的主要内容,如果未能解决你的问题,请参考以下文章

片段(Java) | 机试题+算法思路+考点+代码解析 2023

编程思想与算法

常用编程思想与算法

伪代码

机器学习3_EM算法与混合高斯模型

可以解密加密数据的片段吗?