1、 绪论
数据的组织和问题的规模有关。
解决问题的方法效率跟空间的利用效率有关
解决问题的效率和算法的巧妙程度有关。

抽象数据类型(Abstract Data Type)
- 数据类型
- 数据对象集
- 数据集合相关联的操作集
- 抽象 :不依赖具体的实现
编译器写法:
/*
将n(n>1)个整数存放到一维数组R中,设计一个算法,将R中的序列循环左移P(0<p<n)个位置
*/
#include<iostream>
using namespace std;
//A-交换数组,l-数组交换起点位置,r-数组交换终点位置
void Reverse(int A[],int l,int r)
{
int i,j,temp;
for(i=l,j=r;i<j;++i,--j)
{
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
//a-交换数组,n-数组长度,p-交换点
void RCR(int a[],int n,int p)
{
if(p<=0||p>=n)
{
cout<<"error"<<endl;
}
else
{
Reverse(a,0,p-1);
Reverse(a,p,n-1);
Reverse(a,0,n-1);
}
}
int main()
{
int L;//交换点
int i;//
int R[50];
int n;//数组长度
cout<<"交换点位置L=";
cin>>L;
cout<<"数组长度n=";
cin>>n;
for(i=0;i<n;i++)
{
R[i]=i;
}
for(i=0;i<n;i++)
{
cout<<R[i]<<" ";
}
cout<<endl;
RCR(R,n,L);
for(i=0;i<n;++i)
{
cout<<R[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
纸质写法:
//A-交换数组,l-数组交换起点位置,r-数组交换终点位置
void Reverse(int A[],int l,int r)
{
int i,j,temp;
for(i=l,j=r;i<j;++i,--j)
{
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
//a-交换数组,n-数组长度,p-交换点
void RCR(int a[],int n,int p)
{
if(p<=0||p>=n)
{
cout<<"error"<<endl;
}
else
{
Reverse(a,0,p-1);
Reverse(a,p,n-1);
Reverse(a,0,n-1);
}
}
1.1 结点的构造
先定义一个结点的结构类型,然后用这个结构型制作一个结点。
1.1.1 定义结点的结构类型
凡是结构型(假设名为a)的内部都有这样的指针型(假设名为b),即b是用来存放和a类型相同的结构体变量地址的指针型(结点a的指针next,next所指的结点b与结点a是属于同一结构类型的),则在定义a的typedef struct 语句之后都要加上a这个结构体的名字。
//结构体正常定义
typedef struct
{
int a;
char b;
}TypeA;
结构型结点-链表
typedef struct Node
{
int data;
struct Node *next;//指向Node型变量的指针
}Node;
结构型结点-二叉树
typedef struct BTNode
{
int data;
struct BTNode *lchild;//l
struct BTNode *rchild;//指向右子结点指针}BTNode;
1.1.2 制作结点
1. BTNode BT;
2. BTNode *BT;//定义一个结点指针
BT=(BTNode*)malloc(sizeof(BTNode));用malloc申请一个结点内存空间,最后然指针BT指向这片内存空间
//动态申请数组空间方法
int *p;
p=(int *)malloc(n*sizeof(int));
1.2 函数
1.2.1 传入函数的参数会改变、
void f(int *&x)//指针型变量在函数体中需要改变的写法
{
++x;
}
void g(Slist &s,int x)//s本身发生变化,采用引用型
{
}
void q(Node *c ,int x)//c是一个指向一个链表表头的指针,指针自身不变,因此不需要采用引用型
1.3 时间复杂度分析
将算法中的基本操作的执行次数作为算法时间复杂度的度量。一般按照使基本操作执行次数最多的输入来计算时间复杂度
O(1)≤O(log2(n))≤O(n)≤O(nlog2(n))≤O(n2)≤…≤O(nk)≤O(2^n) n为问题的规模
1.3 数据结构的基本概念
数据 对客观事物的符号表示
数据元素 数据的基本单元,计算机程序中将其作为一个整体进行考虑和处理。一个数据元素可由若干数据项组成。e.g. 一本书的目录为一个数据元素,每一个目为一个数据项
数据项 数据结构中最基本单元,其表示称为数据域
数据对象 性质相同的数据元素的集合,是数据的一个子集。
数据结构 相互存在一种或多种特定关系的数据元素的集合,包括:逻辑结构、存储结构和对数据的运算。
1.3.1 数据的逻辑结构
对数据之间关系的描述,主要有线性结构和非线性结构。
线性结构指数据元素之间存在“一对一”的线性关系的数据结构。
非线性结构指其结点存在“一对多”的关系,可分为树形结构和图形结构
1.3.2 数据的存储结构
包括数据元素的表示和关系的表示。当数据元素是由若干数据项构成时,数据项的表示称为数据域。e.g. 一个链表结点包含值域和指针域。
4种方式:顺序储存方法,链式存储方法,索引存储方法、散列存储方法。
1.4 算法的基本概念
由基本运算及规定的运算顺序所构成的完整的解题步骤。
特点:有穷性,确定性,有输入输出,可行性(有限次)
1.5 练习
1.5.1 二分查找
Position BinarySearch( List L, ElementType X )
{
Position p=NotFound;
int left=1,right=L->Last, mid;
if(X<L->Data[left]||X>L->Data[right])
return p;
while(left<=right)
{
if(X==L->Data[left])
{
p=left;
return p;
}
else if(X ==L->Data[right])
{
p=right;
return p;
}
//当前查找区间为[left,right]
mid=left+(right-left)/2;
/*
使用(low+high)/2会有整数溢出的问题(问题会出现在当low+high的结果
大于表达式结果类型所能表示的最大值时,这样,产生溢出后再/2是不会
产生正确结果的,而low+((high-low)/2)不存在这个问题
*/
if(L->Data[mid]==X)
{
p=mid;
return p;
}
else if(L->Data[mid]>X)//在[left,mid-1]查找
{
right=mid-1;
}
else if(L->Data[mid]<X)//在[mid+1,right]查找
{
left=mid+1;
}
}
return p;
}
1.5.2 最大子列
int MaxSubSum(int a[],int N)
{
int MaxSub=0;
for(int i=0;i<N;++i)
{
int sum=0;
for(int j=i;j<N;j++)
{
sum+=a[j];
if(sum>MaxSub)
MaxSub=sum;
}
}
return MaxSub;
}
int MaxSubSum(int a[],int N)
{
int MaxSub=0,sum=0;
for(int i=0;i<N;++i)
{
sum+=a[i];
if(sum>MaxSub)
MaxSub=sum;
else if(sum<0)
sum=0;
}
return MaxSub;
}
#include<iostream>
using namespace std;
const int maxN=1e5;
int a[maxN],N;//列数
int solve(int left,int right)
{
/*分而治之的方法求List[left]到List[right]的最大子列和*/
if(left==right)
{
/*递归的终止条件,子列只有一个数字*/
return a[left]>0?a[left]:0;
}
/*下面是"分"的过程*/
int mid=left+(right-left)/2;/*中分店*/
/*递归求得两边子列最大和*/
int lans=solve(left,mid);
int rans=solve(mid+1,right);
/*求跨分界线的最大子列和*/
int sum=0,lmax=a[mid],rmax=a[mid+1];
for(int i=mid;i>=left;--i)
{/*从中线向左扫描*/
sum+=a[i];
if(sum>lmax) lmax=sum;
}
sum=0;
for(int i=mid+1;i<=right;++i)
{/*从中线向右扫描*/
sum+=a[i];
if(sum>rmax) rmax=sum;
}
int ans=lmax+rmax;
/*比较*/
ans=(lans>rans)?(lans>ans?lans:ans):(rans>ans?rans:ans);
return ans;
}
int main()
{
int p;
int sum;
cin>>N;
for(int i=0;i<N;++i)
{
cin>>p;
a[i]=p;
}
int ans;
cout<<solve(0,N-1);
return 0;

本文深入探讨了数据结构与算法的基础知识,包括数据的逻辑结构、存储结构、算法的概念及其特性,介绍了抽象数据类型、时间复杂度分析,并提供了二分查找、最大子列和等经典算法的实现。
1961

被折叠的 条评论
为什么被折叠?



