数据结构基础
一、数据结构
1.数据结构是计算机存储,组织数据的方式,是指相互之间存在一种或者多种特定关系的数据元素的集合
2.通过静心选择的数据结构可以带来更高的运行或存储效率
二、数据结构的两个层次及不同结构的划分方法(逻辑结构&物理结构)
比如:你在排队的时候,你在一队人之间,那个叫逻辑结构,而你在地球上的位置是物理位置
1、逻辑结构
数据元素抽象化的相互关系,与数据的存储无关,独立于计算机,它是从具体问题抽象出来的数学模型。反映数据元素之间的逻辑关系
(1)线性结构
有且仅有一个开始和一个终端节点,并且所有结点都最多只有一个字节前趋和一个后继
比如:线性表,栈,队列等
(2)非线性结构
一个结点可能有多个直接前趋和直接后继
比如:树,图等
2、存储结构(物理结构)
数据元素及其关系在计算机存储器中的存储方式
(1)顺序存储结构
在内存中数据按顺序依次连续存储
比如:数组
(2)链式存储结构
在内存中数据可以按次序进行连续存储,也可以不连续存储,通过指示元素存储地址的指针来表示数据元素之间的逻辑关系
比如:链表
**以上两种不同的存储结构在进行数据结构的操作时会导致不一样的操作复杂度
三、数据算法
1、算法的定义
算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令。它代表着用系统的方法描述解决问题的策略机制
2、算法的特征
(1)输入项
有0个或多个输入
(2)输出项
有一个或多个输出,要有结果
(3)确定性
每一步骤必须是确定的,无歧义的
(4)有穷性
必须能在执行有限个步骤之后终止
(5)有效性
每一个步骤都可以在有限时间内完成
3、算法评价
1.正确性
2.高效性(时间复杂度&空间复杂度)
3.健壮性
4.可读性
四、基本排序算法
1、冒泡排序
将大的数往后面排
#include<iostream>
using namespace std;
template<typename T>
void ranks(T* parr, int len)
{
int j=0;
for (int i = 0; i < len-1; i++)
{
for ( j = 0; j < len - 1 - i; j++)//后面不变
{
if (parr[j] > parr[j + 1])
{
parr[j] = parr[j] ^ parr[j + 1];
parr[j+1] = parr[j] ^ parr[j + 1];
parr[j] = parr[j] ^ parr[j + 1];
}
}
}
}
template<typename T>
void ranka(T* parr,int len)
{
int temp=0;//优化,如果写在第二个循环中,那么就会不断开辟临时内存,释放临时内存---时间复杂度
int j;
for(int i=0;i<len-1;i++)
{
for(j=0;j<len-1-i;j++)
{
temp=parr[j];
parr[j]=parr[j+1];
parr[j+1]=temp;
}
}
}
int main()
{
int str[9] = { 0,25,6,3,2,5,2,3,5 };
ranks(str, 9);
for (auto i : str)
{
cout << i << " ";
}
system("pause");
return 0;
}
2、选择排序
将小的数往前面排
#include<iostream>
using namespace std;
template<typename T>
void ranks(T* parr, int len)//选择排序
{
int j = 0;
int temp = 0;
for (int i = 0; i < len - 1; i++)
{
for (j = i; j < len - 1; j++)//前面不变
{
if (parr[i] > parr[j + 1])
{
temp = parr[i];
parr[i] = parr[j + 1];
parr[j + 1] = temp;
}
}
}
}
int main()
{
int str[10] = { 3,2,552,652,5,52,52,5,2,63 };
ranks(str, 10);
for (auto i : str)
{
cout << i << " ";
}
system("pause");
return 0;
}
3、二分查找
二分查找也称折半查找(binary search),它是一种效率较高的查找方法
但是折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列(必须是有序的数据,用二分查找才有意义)
工作原理:将要查找的元素一分为两半,然后一半一半的查找
优点:查找效率高
缺点:顺序表,必须是有序序列
#include<iostream>
using namespace std;
template<typename T>
int binary_search(T* parr, int len, T findval)//将数组,数组长度,要查找的数作为形参
{
//首先这个数组得是顺序的,且后面大于前面
int left = 0;//左边数组元素的下标
int right = len - 1;//右边数组元素的下标
int mid = 0;//数组中间元素下标
while (left <= right)//当左边的下标都比右边的下标大时,就退出循环
{
mid = left + ((right - left) >> 1);//>>右移运算符,可以将数缩小一半,然后随着left和right的更新,mid也随之而更新
if (findval == parr[mid])
{
printf("找到了这个数组元素的下标:");
return mid;//将元素下标返回出来
}
else if (findval > parr[mid])//要找的元素比中间元素要大,更新左边数组下标的值
{
left = mid + 1;//更新left的值,因为mid已经查找了,所以要加1
}
else//要找的元素比中间元素小,更新右边数组下标的值
{
right = mid - 1;//原因和left类似
}
}
printf("数组中没有这个元素");
return -1;
}
int main()
{
int arr[5] = { 1,2,3,4,5 };
double str[5] = { 1.2,3.2,4.2,5.2,6.2 };
cout << binary_search(str, 5, 0.0) << endl;
system("pause");
return 0;
}