1 绪论
实例:
最大子列和
算法一:O(N3)
//算法一
int maxSum1(int a[],int n)
{
int i,j,k;
int thisSum,maxSum=0;
for(i=0;i<N;i++){//子列左端
for(j=0;j<N;j++){//子列右端
thisSum=0;
for(k=i;k<=j;k++){
thisSum+=a[k];
}
if(thisSum>maxSum)
maxSum=thisSum;
}
}
return maxSum;
}
算法二:O(N2)
//算法二
int maxSum2(int a[],int n)
{
int i,j;
int thisSum,maxSum=0;
for(i=0;i<N;i++){
thisSum=0;
for(j=i;j<N;j++){
thisSum+=a[j];
if(thisSum>maxSum)
maxSum=thisSum;
}
}
return maxSum;
}
算法三:O(nlogn)
分治法,递归
//算法三
int max(int a,int b,int c)
{
int max=b;
if(a>b)
max=a;
if(c>max)
max=c;
return max;
}
//一组数字二分,求左边的最大子列和,右边最大子列和以及跨越中间的最大子列和
int divideAndConquer(int a[],int left,int right)
{
int maxLeftSum,maxRightSum;
int maxLeftBorderSum,maxRightBorderSum;
int leftBorderSum,rightBorderSum;
int middle,i;
//递归终止条件
if(left==right)
if(a[left]>0)
return a[left];
else
return 0;
middle=(left+right)/2;
maxLeftSum=divideAndConquer(a,left,middle);//递归调用
maxRightSum=divideAndConquer(a,middle+1,right);//递归调用
//从中间往左边扫描
maxLeftBorderSum=0;leftBorderSum=0;
for(i=middle;i>=left;i--){
leftBorderSum+=a[i];
if(leftBorderSum>maxLeftBorderSum)
maxLeftBorderSum=leftBorderSum;
}
//从中间往右边扫描
maxRightBorderSum=0;rightBorderSum=0;
for(i=middle+1;i<=right;i++){
rightBorderSum+=a[i];
if(rightBorderSum>maxRightBorderSum)
maxRightBorderSum=rightBorderSum;
}
return max(maxLeftSum,maxRightSum,maxLeftBorderSum+maxRightBorderSum);
}
int maxSum3(int a[],int n)
{
return divideAndConquer(a,0,n-1);
}
算法四:O(N)
//算法四
int maxSum4(int a[],int n)
{
int thisSum=0,maxSum=0;
int i;
for(i=0;i<n;i++){
thisSum+=a[i];
if(thisSum>maxSum)
maxSum=thisSum;
if(thisSum<0)//只要thisSum为正,说明对后面的求和起到正向作用
thisSum=0;
}
return maxSum;
}
2 线性表
2.1线性表的定义
逻辑结构:相同特性数据元素,有限,序列
存储结构:
顺序存储->顺序表->数组实现 逻辑上相邻,物理位置上也相邻
链式存储->链表
2.2顺序表
定义类型
#define MAXSIZE 100
typedef struct{
ElemType* data;
int length;
}SqList;
初始化顺序表
Status InitList_Sq(SqList &L)
{
L.data=new ElemType[MAXSIZE];
if(!L.data) exit(OVERFLOW);//存储分配失败
L.length=0;
return OK;
}
销毁
void DestroyList(SqList &L)
{
delete L.data;
}
清空
void ClearList(SqList &L)
{
L.length=0;
}
求表长
int GetLength(SqList L)
{
return L.length;
}
判断是否为空表
int IsEmpty(SqList L)
{
if(L.length==0) return 1;
else return 0;
}
获取元素值
int GetElem(SqList L,int i,ElemType &e)
{
if(i<=0||i>L.length) return ERROR;
e=L.data[i-1];
return OK;
}
按值查找
int LocateElem(SqList L,ElemType e)
{
int i;
for(i=0;i<L.length;i++){
if(L.data[i]==e)
return i+1;
}
return 0;
}
插入数据
判断插入位置是否合理
判断表是否满
将元素向后移动
给第i个元素赋值
表长++
Status ListInsert(SqList &L,int i,ElemType e)
{
int j;
if(i<=0||i>L.length+1) return ERROR;//判断位置是否合法
if(L.length==MAXSIZE) return ERROR;//判断空间是否满
for(j=L.length-1;j>=i-1;j--)
L.data[j+1]=L.data[j];
L.data[i-1]=e;
L.length++;
return OK;
}
删除元素
Status ListDelete_Sq(SqList &L,int i)
{
int j;
if(i<=0||i>L.length) return ERROR;
for(j=i;j<=L.length-1;j++)
L.data[j-1]=L.data[j];
L.length--;
return OK;
}
#define MAXSIZE 100
typedef struct{
ElemType* data;
int length;
}SqList;
Status InitList_Sq(SqList &L)
{
L.data=new ElemType[MAXSIZE];
if(!L.data) exit(OVERFLOW);//存储分配失败
L.length=0;
return OK;
}
void DestroyList(SqList &L)
{
delete L.data;
}
void ClearList(SqList &L)
{
L.length=0;
}
int GetLength(SqList L)
{
return L.length;
}
int IsEmpty(SqList L)
{
if(L.length==0) return 1;
else return 0;
}
int GetElem(SqList L,int i,ElemType &e)
{
if(i<=0||i>L.length) return ERROR;
e=L.data[i-1];
return OK;
}
int LocateElem(SqList L,ElemType e)
{
int i;
for(i=0;i<L.length;i++){
if(L.data[i]==e)
return i+1;
}
return 0;
}
Status ListInsert(SqList &L,int i,ElemType e)
{
int j;
if(i<=0||i>L.length+1) return ERROR;//判断位置是否合法
if(L.length==MAXSIZE) return ERROR;//判断空间是否满
for(j=L.length-1;j>=i-1;j--)
L.data[j+1]=L.data[j];
L.data[i-1]=e;
L.length++;
return OK;
}
Status ListDelete_Sq(SqList &L,int i)
{
int j;
if(i<=0||i>L.length) return ERROR;
for(j=i;j<=L.length-1;j++)
L.data[j-1]=L.data[j];
L.length--;
return OK;
}
2.3链表
2.3.1单链表
操作
定义单链表类型
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
初始化单链表
头插法
尾插法
判断链表是否为空
销毁链表
清空链表
求链表表长
取值
按值查找
插入元素
删除元素
//定义链表类型
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
//单链表的初始化
Status InitList_L(LinkList &L)
{
L=new LNode;
L->next=NULL;
return OK;
}
//头插法
void CreateList_H(LinkList &L,int n)
{
int i;
L=new LNode;
LNode*p;
L->next=NULL;
for(i=n;i>0;i--){
p=new LNode; cin>>p->data;
p->next=L->next;
L->next=p;
}
}
//尾插法
void CreateList_R(LinkList &L,int n)
{
LNode *s,*r;
L=new LNode;
L->next=NULL;
r=L;
for(int i=0;i<n;i++){
s=new LNode; cin>>s->data;
r->next=s;
r=s;
}
r->next=NULL;
}
//判断链表是否为空
int ListEmpty(LinkList L)
{
if(L->next) return 0;
else return 1;
}
//销毁链表
Status DestroyList(LinkList &L)
{
LNode*p;
while(L){
p=L;
L=L->next;
delete p;
}
return OK;
}
//清空链表
Status ClearList(LinkList &L)
{
LNode *p,*q;
p=L->next;
while(p){
q=p->next;
delete p;
p=q;
}
L->next=NULL;
return OK;
}
//求单链表表长
int ListLength_L(LinkList L)
{
LNode*p;
p=L->next;
int i=0;
while(p){
i++;
p=p->next;
}
return i;
}
//取值,取单链表中第i个元素
Status GetElem_L(LinkList L,int i,ElemType &e)
{
int j=0;
LNode*p=L;
if(i<=0) return ERROR;
while(j<i&&p){
j++;
p=p->next;
}
if(!p) return ERROR;
e=p->data;
return OK;
}
//按值查找,返回位置序号
int LocateElem_L(LinkList L,ElemType e)
{
int i=1;
LNode*p=L->next;
while(p->data!=e&&p){
p=p->next;
i++;
}
if(p) return i;
else return 0;
}
//插入,在第i个结点前插入值为e的新结点
Status ListInsert_L(LinkList &L,int i,ElemType e)
{
LNode*p=L,*s;
int j=0;
if(i<=0) return ERROR;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p) return ERROR;
s=new LNode; s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
//删除第i个结点
Status ListDelete_L(LinkList &L,int i,ElemType &e)
{
LNode *p=L,*q;
int j=0;
if(i<=0) return ERROR;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p) return ERROR;
else{
q=p->next;
if(q==NULL) return ERROR;
e=q->data;
p->next=q->next;
delete q;
return OK;
}
}
2.3.2循环链表
循环单链表
带尾指针的循环单链表的合并
2.3.3双链表
结点类型
typedef struct DulNode{
ElemType data;
struct DulNode *prior,*next;
}DulNode,*DulLinkList;
双链表的对称性
指针p指向某结点
p->next->prior=p=p->prior->next;