1 顺序表中基本操作的实现
1.1 顺序表的初始化
编程思想:
一:给基地址分配一个大小为MAXSIZE的数组空间
二:对基地址判断是否为空,成功则令数组当前长度为0,并返回OK,失败则exit
1.2 取值
取值操作是根据指定的位置序号i,获取顺序表中第i个元素的值
编程思想:
一:判断i的值是否合理
二:不合理则返回错误,合理则进行赋值
1.3 顺序表的查找
查找与e值相等的元素,并返回该元素序号
编程思想:
一:进行循环判断,相等则返回序号,不相等则返回错误
1.4 顺序表的插入
编程思想:
一:判断插入的位置是否合理,不合理则返回错误,合理则进行(二)步骤
二:判断当前长度是否以达到最大值,达到则返回错误,未达到则进行(三)步骤
三:将要插入的位置的元素及后面所有的元素后移一位
四:顺序表长度加1,并返回OK
1.5顺序表的删除
编程思想:
一:判断i值是否合理,不合理则返回错误,合理则进行(二)步骤
二:将位置为i+1的元素及后面所有的元素向前移动一位
三:顺序表长度减1,返回OK
1.6 代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define MAXSIZE 100
#define OK 0
#define ERROR 1
using namespace std;
typedef int Status;
typedef int ElemType;
typedef struct{
int Length;
ElemType *elem;
}SqList;
/* 顺序表的初始化 */
Status InitList(SqList &List){
List.elem=new ElemType[MAXSIZE];
if(!List.elem)
exit(ERROR);
List.Length=0;
return OK;
}
/* 取值 */
Status GetElem(SqList &List,int i,ElemType &e){
if(i<1||i>List.Length)
return ERROR;
e=List.elem[i-1];
return e;
}
/* 顺序表的查找 */
int SearchElem(SqList List,ElemType e){
int i;
for(i=0;i<List.Length;i++)
if(List.elem[i]==e) return i+1;
return -1; //区分
//注意不可以把return -1放入循环,因为一旦遇到未执行就结束了函数
}
/* 顺序表的插入 */
Status InsertElem(SqList &List,int i,ElemType e){
int j,k;
if((i<1)||(i>List.Length)) return ERROR;
if(List.Length>=MAXSIZE) return ERROR;
for(j=List.Length-1;j>=i-1;j--){
List.elem[j+1]=List.elem[j];
}
List.elem[i-1]=e;
List.Length++;
return OK;
}
/* 顺序表的删除 */
Status DeleteElem(SqList &List,int i){
int j;
if((i<1)||(i>List.Length)) return ERROR;
for(j=i-1;j<List.Length;j++){
List.elem[j]=List.elem[j+1];
}
List.Length--;
return OK;
}
/* 存入数据 */
Status StoraElem(SqList &List){
int num,i;
cout<<"Please input the number of elems:";
cin>>num;
cout<<"Please store data:"<<"\n";
for(i=0;i<num;i++){
cin>>List.elem[i];
}
List.Length=num;
return OK;
}
/* 输出 */
Status OutPut(SqList List){
int i;
for(i=0;i<List.Length;i++){
cout<<List.elem[i]<<"\t";
}
cout<<"\n";
return OK;
}
Status main(){
int e=0,i;
SqList List;
InitList(List);
StoraElem(List);
OutPut(List);
cout<<"Please input the number of the data you want to get:";
cin>>i;
e=GetElem(List,i,e);
cout<<"number:"<<i<<"\t"<<"data:"<<e<<"\n";
cout<<"Please input the data you want search:";
cin>>e;
cout<<"The number of e is:"<<SearchElem(List,e)<<"\n";
cout<<"Please insert the data:";
cin>>e;
cout<<"Please input the place :";
cin>>i;
InsertElem(List,i,e);
OutPut(List);
cout<<"Please input the number of the data you want to delete:";
cin>>i;
DeleteElem(List,i);
OutPut(List);
return OK;
}
2 单链表中基本操作的实现
2.1 初始化
编程思想:
一:为头节点分配空间
二:头节点指针域置为nulll,返回
2.2 前插法创建单链表
主要编程思想:
p->next=L->next;L->next=p;
第一次将p->next置为NULL;
以后每一次将p->next(新节点的指针域)置为L->next(L后面那个节点的空间地址)
2.3 尾插法创建单链表
主要编程思想:
r=L;
//
//
//
p->next=NULL;r->next=p;
因为要不断移动指针,所以要令r=L
2.4 取值
编程思想:
一:使p指向首元节点
二:循环直到p为空或p指向第i个元素(结束情况1:p为空;结束情况2:p指向第i个元素),注意这里是&&而不是||好好理解。
三:判断p为空或者j>i(因为链表不是随机存储不好直接判断长度,所以将判断j>i放在这里,而不是放在前面),是则返回错误,不是则赋值
四:返回
2.5单链表的按值查找
编程思想:
一:p指向首元节点
二:循环直到p为空或者p所指节点的数据域等于e(结束情况1:p为空;结束情况2:p所指节点的数据域等于e)
三:返回
2.6单链表的插入
编程思想:
一:p指向头节点
二:循环直至p为空或者指向第i-1节点(结束情况1:p为空;结束情况2:指向第i-1的节点)
三:判断p为空或者j>i-1,是则返回错误,不是则进行插入操作
2.7 单链表的删除
编程思想:
一:p指向头节点;
二:循环直至p->next为空或者指向第i-1的节点(结束情况1:p->next为空;结束情况2:指向第i-1的节点)
2
三:判断p->next为空或者j>i-1,是则返回错误,不是则进行删除操作
2.8 代码
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#define OK 0
#define ERROR 1
using namespace std;
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType Data;
struct LNode *next;
}LNode,*LinkList;
/* 初始化 */
Status InitList(LinkList &L){
L=new LNode; //L指向一个空间
L->next=NULL; //空间的下一个空间为NULL
return OK;
}
/* 取值 */
Status GetElem(LinkList L,ElemType &e,int i){
int j=1;
LinkList p=new LNode;
p=L->next;
while(p&&j<i){
p=p->next;
j++;
}
if(!p||j>i) return ERROR;
e=p->Data;
return OK;
}
/* 单链表的按值查找 */
LinkList SearchElem(LinkList L,ElemType e){
LinkList p=new LNode;
p=L->next;
while(p->Data!=e&&p){
p=p->next;
}
return p;
}
/* 单链表的插入 */
Status Insert(LinkList &L,int i,ElemType e){
LinkList p;
LinkList Node=new LNode;
int j=1;
p=L->next;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
Node->Data=e;
Node->next=p->next;
p->next=Node;
return OK;
}
/* 单链表的删除 */
Status Delete(LinkList &L,int i){
LinkList p=new LNode;
LinkList q=new LNode;
int j=1;
p=L->next;
while(!p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
delete q;
return OK;
}
/* 前插法创建链表 */
void CreateList_H(LinkList &L,int n){
int i;
LinkList p;
L=new LNode;
L->next=NULL;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=L->next;
L->next=p;
}
}
/* 尾插法链表 */
void CreateList_T(LinkList &L,int n){
int i;
LinkList t;
LinkList p;
L=new LNode;
L->next=NULL;
t=L;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=NULL;
t->next=p;
t=p;
}
}
/* 输出 */
Status OutPut(LinkList L){
L=L->next;
while(L){ //先判断当前空间是否为空在输出当前空间
cout<<L->Data<<' ';
L=L->next;
}
return OK;
}
int main(){
int Num,i;
ElemType e;
LinkList L;
cout<<"Please input the num of the data:";
cin>>Num;
CreateList_T(L,Num);
cout<<"Please input the number of the data you want to get:";
cin>>i;
GetElem(L,e,i);
cout<<"number:"<<i<<"\t"<<"data:"<<e<<"\n";
cout<<"Please insert the data:";
cin>>e;
cout<<"Please input the place :";
cin>>i;
Insert(L,i,e);
OutPut(L);
cout<<"\n";
cout<<"Please input the number of the data you want to delete:";
cin>>i;
Delete(L,i);
OutPut(L);
return OK;
}
3 线性表的应用
3.1 顺序表的合并
编程思想:
一:循环按序判断List1中是否有List2的元素,有则加入List1的尾部
3.2 顺序表的有序合并
编程思想:
一:创建一个长度等于两个顺序表长度之和的顺序表
二:创建5个指针分别指向合并顺序表的首地址,顺序表1的首地址,顺序表2的首地址,顺序表1的尾地址,顺序表2的尾地址
三:循环直至有一个顺序表1或者顺序表2到达表尾
四:判断大小,将小的数据移入合并表中
五:将未到达表尾的顺序表接到合并表上
3.3 顺序表合并有序and无序代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define MAXSIZE 100
#define OK 0
#define ERROR 1
using namespace std;
typedef int Status;
typedef int ElemType;
typedef struct{
int Length;
ElemType *elem;
}SqList;
/* 顺序表的初始化 */
Status InitList(SqList &List){
List.elem=new ElemType[MAXSIZE];
if(!List.elem)
exit(ERROR);
List.Length=0;
return OK;
}
/* 取值 */
int GetElem(SqList &List,int i,ElemType &e){
if(i<1||i>List.Length)
return ERROR;
e=List.elem[i-1];
return e;
}
/* 顺序表的查找 */
int SearchElem(SqList List,ElemType e){
int i;
for(i=0;i<List.Length;i++)
if(List.elem[i]==e) return i+1;
return -1; //区分
//注意不可以把return -1放入循环,因为一旦遇到未执行就结束了函数
}
/* 顺序表的插入 */
Status InsertElem(SqList &List,int i,ElemType e){
int j,k;
if((i<1)||(i>List.Length+1)) return ERROR;
if(List.Length>=MAXSIZE) return ERROR;
for(j=List.Length-1;j>=i-1;j--){
List.elem[j+1]=List.elem[j];
}
List.elem[i-1]=e;
List.Length++;
return OK;
}
/* 存入数据 */
Status StoraElem(SqList &List){
int num,i;
cout<<"Please input the number of elems:";
cin>>num;
cout<<"Please store data:"<<"\n";
for(i=0;i<num;i++){
cin>>List.elem[i];
}
List.Length=num;
return OK;
}
/* 输出 */
Status OutPut(SqList List){
int i;
for(i=0;i<List.Length;i++){
cout<<List.elem[i]<<"\t";
}
return OK;
}
/* 合并顺序表 */
Status Combine(SqList &List1,SqList &List2){
int i,j;
if(List2.Length+List1.Length>MAXSIZE) return ERROR;
for(i=List1.Length,j=0;j<List2.Length;i++,j++){
List1.elem[i]=List2.elem[j];
List1.Length++;
}
return OK;
}
/* 有序表的有序合并 */
Status Combine_Order(SqList &List1,SqList &List2){
int i,j,k,SIZE;
SqList ComList;
SIZE=List2.Length+List1.Length;
if(!ComList.elem)
exit(ERROR);
ComList.Length=0;
ComList.elem=new ElemType[SIZE];
ComList.Length=SIZE;
for(i=0,j=0,k=0;i<List1.Length&&j<List2.Length;){
if(List1.elem[i]<=List2.elem[j]){
ComList.elem[k]=List1.elem[i];
i++;
k++;
}
else{
ComList.elem[k]=List2.elem[j];
j++;
k++;
}
}
if(i==List1.Length){
while(j<List2.Length){
ComList.elem[k]=List2.elem[j];
k++;
j++;
}
}
if(j==List2.Length){
while(i<List1.Length){
ComList.elem[k]=List1.elem[i];
k++;
i++;
}
}
for(i=0;i<ComList.Length;i++){
cout<<ComList.elem[i]<<" ";
}
return OK;
}
/* 合并顺序表2 */
Status MergeList(SqList &List1,SqList &List2){
int m,n,i,e,t;
m=List1.Length;
n=List2.Length;
m=m+1;
for(i=0;i<n;i++){
e=GetElem(List2,i+1,e);
t=SearchElem(List1,e);
if(t<0){
InsertElem(List1,m++,e);
}
}
return OK;
}
/* 有序顺序表的有序合并2 */
SqList MergeList_Order(SqList &List1,SqList &List2){
int SIZE,i;
int *pc,*p1,*p1_last,*p2,*p2_last;
SqList ComList;
SIZE=List2.Length+List1.Length;
ComList.elem=new ElemType[SIZE];
ComList.Length=SIZE;
pc=ComList.elem;
p1=List1.elem;
p1_last=List1.elem+List1.Length-1;
p2=List2.elem;
p2_last=List2.elem+List2.Length-1;
while(p1<=p1_last&&p2<=p2_last){
if(*p1<=*p2) *pc++=*p1++;
else *pc++=*p2++;
}
while(p2<=p2_last) *pc++=*p2++;
while(p1<=p1_last) *pc++=*p1++;
return ComList;
/* for(i=0;i<ComList.Length;i++){
cout<<ComList.elem[i]<<" ";
}
return OK; */
}
/* 主函数 */
Status main(){
int e=0,i;
SqList List1;
SqList List2;
SqList ComList;
InitList(List1);
InitList(List2);
StoraElem(List1);
OutPut(List1);
cout<<"\n";
StoraElem(List2);
OutPut(List2);
cout<<"\n";
cout<<"The list combined(order):"<<endl;
/* MergeList(List1,List2);
OutPut(List1); */
ComList=MergeList_Order(List1,List2);
OutPut(ComList);
return OK;
}
3.4 链表的合并
编程思想:
一:循环按序判断L中是否有L2的元素,有则加入L1的尾部
3.5 链表的有序合并
编程思想:
一:p1指向L1的首元节点,p2指向L2的首元节点,pc指向ComL的头节点
二:判断大小,将小的插入到ComL中
三:将非空表的剩余段插入到ComL中
四:删除L2头节点
3.5 链表合并有序and无序代码
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define OK 0
#define ERROR 1
typedef int ElemType;
typedef int Status;
typedef struct LNode{
struct LNode *next;
ElemType Data;
}LNode,*LinkList;
/* 初始化 */
Status InitList(LinkList &L){
L=new LNode; //L指向一个空间
L->next=NULL; //空间的下一个空间为NULL
return OK;
}
/* 取值 */
Status GetElem(LinkList L,ElemType &e,int i){
int j=1;
LinkList p=new LNode;
p=L->next;
while(p&&j<i){
p=p->next;
j++;
}
if(!p||j>i) return ERROR;
e=p->Data;
return OK;
}
/* 单链表的按值查找 */
LinkList SearchElem(LinkList L,ElemType e){
LinkList p=new LNode;
p=L->next;
while(p->Data!=e&&!p){
p=p->next;
}
return p;
}
/* 单链表的插入 */
Status Insert(LinkList &L,int i,ElemType e){
LinkList p;
LinkList Node=new LNode;
int j=1;
p=L->next;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
Node->Data=e;
Node->next=p->next;
p->next=Node;
return OK;
}
/* 前插法创建链表 */
void CreateList_H(LinkList &L,int n){
int i;
LinkList p;
L=new LNode;
L->next=NULL;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=L->next;
L->next=p;
}
}
/* 尾插法链表 */
void CreateList_T(LinkList &L,int n){
int i;
LinkList t;
LinkList p;
L=new LNode;
L->next=NULL;
t=L;
/* cout<<"Please input data:"; */
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=NULL;
t->next=p;
t=p;
}
}
/* 输出 */
Status OutPut(LinkList L){
L=L->next;
while(L){ //先判断当前空间是否为空再输出当前空间
cout<<L->Data<<' ';
L=L->next;
}
cout<<"\n";
return OK;
}
/* 测量链表长度 */
int MeasureList(LinkList L){
int i=1;
LinkList p;
if(!L||!L->next) return 0;
p=L->next;
while(p){
p=p->next;
i++;
}
return i-1;
}
/* 链表的有序合并 */
LinkList Combine_Order(LinkList &L1,LinkList L2){
LinkList p1,p2,pc,ComL;
p1=L1->next;
p2=L2->next;
ComL=new LNode;
pc=ComL;
while(p1&&p2){
if(p1->Data==p2->Data){
pc->next=p1;
pc=pc->next;
p1=p1->next;
p2=p2->next;
}
else{
if(p1->Data<=p2->Data){
pc->next=p1;
pc=pc->next; //等效于pc=p1;
p1=p1->next;
}
else{
pc->next=p2;
pc=pc->next; //等效于pc=p2
p2=p2->next;
}
}
}
pc->next=p1?p1:p2;
delete L2;
return ComL;
}
/* 链表合并 */
Status Combine(LinkList &L1,LinkList &L2){
int i;
int Length;
ElemType e;
LinkList p;
LinkList q;
i=1;
q=L2->next;
while(q){
Length=MeasureList(L1);
GetElem(L2,e,i);
p=SearchElem(L1,e);
if(!p) q=q->next;
else{
Insert(L1,Length+1,e);
q=q->next;
i++;
}
}
return OK;
}
/* 主函数 */
int main(){
int Num;
int Length;
ElemType e;
LinkList L1;
LinkList L2;
LinkList ComL;
cout<<"Please input the num of List1 data:";
cin>>Num;
CreateList_T(L1,Num);
OutPut(L1);
Length=MeasureList(L1);
cout<<"Length:"<<Length<<"\n";
cout<<"Please input the num of List2 data:";
cin>>Num;
CreateList_T(L2,Num);
OutPut(L2);
Length=MeasureList(L1);
cout<<"Length:"<<Length<<"\n";
cout<<"The coombined list:"<<"\n";
ComL=Combine_Order(L1,L2);
OutPut(ComL);
/* Combine(L1,L2);
OutPut(L1); */
return OK;
}
3.6 多项式的创建
编程思想:
一:创建带有头节点p的单链表
二:找到头节点(pre)和第一个节点(q)(数据需要插入其中)
三:循环生成节点s并输入系数和指数
四:循环判断q为空并且q的系数小于s的系数,若满足循环条件的将pre和q后移
五:插入
3.7 多项式相加
编程思想:
一:创建p1,p2.pc使p1=Pa->next(p1指向Pa的首元节点),p2=Pb->next(p2指向Pb的首元节点);pc=Pa(p3指向Pa的头节点);
二:循环内判断1:p1->expn == p2->expn;
2:p1->expn < p2->expn
3:p1->expn > p2->expn
三:1:判断sum(=p1->coef+p2->coef)是否等于零
1.1:等于零:p1后移,并删除p1;p2后移,并删除Pb当前节点
1.2:不为零:p1的coef等于sum;pc链接p1;p3后移(pc=p1);p1后移;删除Pb当前节点
2:将p1连接在pc后;p1,p3后移;
3:将p2连接在pc后;p2,p3后移;
四:插入非空多项式的剩余段,删除Pb的头节点
3.8 多项式代码
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define OK 0
#define ERROR 1
typedef int ElemType;
typedef int Status;
typedef struct PNode{
float coef;
int expn;
struct PNode *next;
}PNode,*Polynomial;
/* 输出 */
Status OutPut(Polynomial P){
P=P->next;
while(P){ //先判断当前空间是否为空在输出当前空间
cout<<P->coef<<"X"<<P->expn<<' ';
P=P->next;
}
cout<<"\n";
return OK;
}
/* 多项式的创建 */
void CreatePolyn(Polynomial &P,int n){
int i;
Polynomial s,q,pre;
P=new PNode;
P->next=NULL;
for(i=0;i<n;i++){
pre=P;
q=pre->next;
s=new PNode;
cin>>s->coef>>s->expn;
while(q&&q->expn<s->expn){
pre=q;
q=q->next;
}
s->next=q;
pre->next=s;
}
}
/* 多项式合并 */
void AddPolyn(Polynomial &Pa,Polynomial &Pb){
Polynomial r,p1,p2,pc;
int sum;
p1=Pa->next;
p2=Pb->next;
pc=Pa;
while(p1&&p2){
if(p1->expn==p2->expn){
sum=p1->coef+p2->coef;
if(sum==0){
r=p1;p1=p1->next;delete r;
r=p2;p2=p2->next;delete r;
}
else{
p1->coef=sum;
pc=p1;
p1=p1->next;
r=p2;p2=p2->next;delete r;
}
}
else if(p1->expn<p2->expn){
pc->next=p1;
p1=p1->next;
pc=pc->next;
}
else{
pc->next=p2;
p2=p2->next;
pc=pc->next;
}
}
pc->next=p1?p1:p2;
delete Pb;
}
/* 主函数 */
int main(){
Polynomial Pa;
Polynomial Pb;
int n;
cout<<"请输入多项式的项数:";
cin>>n;
CreatePolyn(Pa,n);
OutPut(Pa);
cout<<"请输入多项式的项数:";
cin>>n;
CreatePolyn(Pb,n);
OutPut(Pb);
AddPolyn(Pa,Pb);
OutPut(Pa);
}
4 线性表作业
4.1 删除单链表中最大的元素
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#define OK 0
#define ERROR 1
using namespace std;
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType Data;
struct LNode *next;
}LNode,*LinkList;
/* 初始化 */
Status InitList(LinkList &L){
L=new LNode; //L指向一个空间
L->next=NULL; //空间的下一个空间为NULL
return OK;
}
/* 单链表的按值查找 */
int SearchElem(LinkList L,ElemType e){
int i;
i=1;
LinkList p=new LNode;
p=L->next;
while(p->Data!=e&&p){
p=p->next;
i++;
}
return i;
}
/* 单链表的删除 */
Status Delete(LinkList &L,int i){
LinkList p=new LNode;
LinkList q=new LNode;
int j=1;
p=L->next;
while(p&&j<i-1){
p=p->next;
j++;
}
if(j==1){
L->next=p->next;
delete p;
}
else{
if((!p||j>i-1)) return ERROR;
q=p->next;
p->next=q->next;
delete q;
}
return OK;
}
/* 前插法创建链表 */
void CreateList_H(LinkList &L,int n){
int i;
LinkList p;
L=new LNode;
L->next=NULL;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=L->next;
L->next=p;
}
}
/* 尾插法链表 */
void CreateList_T(LinkList &L,int n){
int i;
LinkList t;
LinkList p;
L=new LNode;
L->next=NULL;
t=L;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=NULL;
t->next=p;
t=p;
}
}
/* 输出 */
Status OutPut(LinkList L){
L=L->next;
cout<<"The data of list:";
while(L){ //先判断当前空间是否为空在输出当前空间
cout<<L->Data<<' ';
L=L->next;
}
return OK;
}
/* 寻找最大值 */
Status SearchMax(LinkList L){
LinkList p;
int i;
i=1;
p=new LNode;
L=L->next;
p->Data=L->Data;
while(L){
if(p->Data<L->Data){
p->Data=L->Data;
i++;
}
L=L->next;
}
return p->Data;
}
int main(){
int Num,i;
ElemType e;
LinkList L;
cout<<"Please input the num of List:";
cin>>Num;
CreateList_T(L,Num);
e=SearchMax(L);
i=SearchElem(L,e);
Delete(L,i);
OutPut(L);
return OK;
}
4.2 单链表逆置
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#define OK 0
#define ERROR 1
using namespace std;
typedef int Status;
typedef int ElemType;
typedef struct LNode{
ElemType Data;
struct LNode *next;
}LNode,*LinkList;
/* 初始化 */
Status InitList(LinkList &L){
L=new LNode; //L指向一个空间
L->next=NULL; //空间的下一个空间为NULL
return OK;
}
/* 取值 */
Status GetElem(LinkList L,ElemType &e,int i){
int j=1;
LinkList p=new LNode;
p=L->next;
while(p&&j<i){
p=p->next;
j++;
}
if(!p||j>i) return ERROR;
e=p->Data;
return OK;
}
/* 单链表的按值查找 */
LinkList SearchElem(LinkList L,ElemType e){
LinkList p=new LNode;
p=L->next;
while(p->Data!=e&&!p){
p=p->next;
}
return p;
}
/* 单链表的插入 */
Status Insert(LinkList &L,int i,ElemType e){
LinkList p;
LinkList Node=new LNode;
int j=1;
p=L->next;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
Node->Data=e;
Node->next=p->next;
p->next=Node;
return OK;
}
/* 单链表的删除 */
Status Delete(LinkList &L,int i){
LinkList p=new LNode;
LinkList q=new LNode;
int j=1;
p=L->next;
while(p&&j<i-1){
p=p->next;
j++;
}
if(!p||j>i-1) return ERROR;
q=p->next;
p->next=q->next;
delete q;
return OK;
}
/* 前插法创建链表 */
void CreateList_H(LinkList &L,int n){
int i;
LinkList p;
L=new LNode;
L->next=NULL;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=L->next;
L->next=p;
}
}
/* 尾插法链表 */
void CreateList_T(LinkList &L,int n){
int i;
LinkList t;
LinkList p;
L=new LNode;
L->next=NULL;
t=L;
cout<<"Please input data:";
for(i=0;i<n;i++){
p=new LNode;
cin>>p->Data;
p->next=NULL;
t->next=p;
t=p;
}
}
/* 输出 */
Status OutPut(LinkList L){
L=L->next;
while(L){ //先判断当前空间是否为空在输出当前空间
cout<<L->Data<<' ';
L=L->next;
}
cout<<"\n";
return OK;
}
/* 测量链表长度 */
int MeasureList(LinkList L){
int i=1;
LinkList p;
if(!L||!L->next) return 0;
p=L->next;
while(p){
p=p->next;
i++;
}
return i-1;
}
/* 逆置 */
Status ReverseList(LinkList &L){
int i,Length;
LinkList p;
LinkList q;
LinkList r;
Length=MeasureList(L)-1;
p=L->next;
while(Length){
if(Length!=1){
r=L->next;
q=p->next;
p->next=q->next;
q->next=r;
L->next=q;
}
else{
r=L->next;
q=p->next;
q->next=r;
L->next=q;
p->next=NULL;
}
Length--;
}
return OK;
}
int main(){
int Num,i;
ElemType e;
LinkList L;
cout<<"Please input the num of the data:";
cin>>Num;
CreateList_T(L,Num);
/* cout<<"Please input the number of the data you want to get:";
cin>>i;
GetElem(L,e,i);
cout<<"number:"<<i<<"\t"<<"data:"<<e<<"\n";
cout<<"Please insert the data:";
cin>>e;
cout<<"Please input the place :";
cin>>i;
Insert(L,i,e);
OutPut(L);
cout<<"\n";
cout<<"Please input the number of the data you want to delete:";
cin>>i;
Delete(L,i); */
cout<<"List:"<<"\n";
OutPut(L);
cout<<"Reversed List:"<<"\n";
ReverseList(L);
OutPut(L);
return OK;
}
5 顺序栈的表示和实现
5.1 顺序栈的初始化
编程思想:
一:给S.base分配空间
二:判断是否分配成功,分配失败则exit
三:S.top=S.base
四:确定栈的的容量
5.2 入栈
编程思想:
一:判断栈是否满了,满了则返回错误
二:未满则在栈顶插入一个新元素,并将栈顶指针上移
5.3 出栈
编程思想:
一:判断栈是否为空,空则返回错误
二:不空则S.top下移,移动后赋值给e
5.4 取栈顶元素
编程思想:
一:判断栈是否为空,空则返回错误
二:不空返回(S.top-1)*
5.5 代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define OK 0
#define ERROR 1
#define MAXSIZE 100
using namespace std;
typedef int SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
/* 顺序栈的初始化 */
Status InitStack(SqStack &S){
S.base=new SElemType[MAXSIZE];
if(!S.base) exit(ERROR);
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
/* 入栈 */
Status Push(SqStack &S,SElemType e){
if(S.top-S.base==S.stacksize) return ERROR; //值得注意的是S.top-S.base得出来的是元素空间个数
*S.top++=e; //S.top不储存数据
return OK;
}
/* 出栈 */
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
/* 取栈顶元素 */
SElemType GetTop(SqStack S){
if(S.top==S.base) return ERROR;
return *(S.top-1);
}
/* 存储数据 */
Status StoreData(SqStack &S){
int num,i;
if(S.base!=S.top) return ERROR;
else{
cout<<"Please input the num of data:";
cin>>num;
cout<<"Please input the data:"<<endl;
for(i=0;i<num;i++){
cin>>S.base[i];
S.top++;
}
}
return OK;
}
/* 输出 */
Status OutPut(SqStack S){
if(S.base==S.top) return ERROR;
else{
cout<<"data of stack:"<<endl;
do{
cout<<*--S.top<<" ";
}
while(S.top!=S.base);
}
cout<<"\n";
return OK;
}
/* 主函数 */
int main(){
SElemType e;
SqStack S;
InitStack(S);
StoreData(S);
OutPut(S);
cout<<"Please push the wanted data:";
cin>>e;
Push(S,e);
OutPut(S);
cout<<"After pop:"<<endl;
Pop(S,e);
OutPut(S);
e=GetTop(S);
cout<<"The top data of stack: "<<e<<endl;
}
6 链栈的表示和实现
6.1 初始化
编程思想:
一:将指针置空
6.2 链栈入栈
编程思想:
一:创建一个新节点,并存入数据
二:将新节点插入栈顶
三:移动S至栈顶
ps:S相当于尾指针,为NULL
6.3 出栈
编程思想:
一:判断栈是否为空,为空则返回ERROR
二:不为空则将栈顶元素赋值给e
三:栈顶指针下移
四:删除栈顶元素
6.4 取栈顶元素
编程思想:
一:判断栈是否为空,为空则返回ERROR
二:不为空则返回栈顶元素,栈顶指针不变
6.5 遍历链栈各个节点
编程思想:
一:递归终止条件为p为NULL,为空则返回
二:输出当前节点的Data
三:再次调用函数
6.6 代码
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#define OK 0
#define ERROR 1;
using namespace std;
typedef int ElemType;
typedef int Status;
typedef struct StackNode{
ElemType Data;
struct StackNode *next;
}StackNode,*LinkStack;
/* 初始化 */
Status InitStack(LinkStack &S){
S=NULL;
return OK;
}
/* 链栈的入栈 */
Status Push(LinkStack &S,ElemType e){
LinkStack p=new StackNode;
p->Data=e;
p->next=S;
S=p;
return OK;
}
/* 出栈 */
Status Pop(LinkStack &S,ElemType &e){
LinkStack p;
if(!S) return ERROR;
e=S->Data;
p=S;
S=S->next;
delete p;
return OK;
}
/* 取栈顶元素 */
ElemType GetTop(LinkStack p){
if(!p) return ERROR;
return p->Data;
}
/* 遍历 */
void TraverseList(LinkStack p){
if(p==NULL) return;
cout<<p->Data<<" ";
TraverseList(p->next);
}
/* 储存数据 */
Status StoreData(LinkStack &p){
int num,i;
LinkStack q;
cout<<"Please input the num of data:";
cin>>num;
cout<<"Please input data:"<<endl;
for(i<0;i<num;i++){
q=new StackNode;
cin>>q->Data;
q->next=p;
p=q;
}
return OK;
}
/* 主函数 */
int main(){
LinkStack p;
ElemType e;
InitStack(p);
StoreData(p);
cout<<"The data of stack:"<<endl;
TraverseList(p);
cout<<"\n";
cout<<"Please push the wanted data:";
cin>>e;
Push(p,e);
TraverseList(p);
cout<<"\n";
cout<<"After pop:"<<endl;
Pop(p,e);
cout<<"The data of stack:"<<endl;
TraverseList(p);
cout<<"\n";
e=GetTop(p);
cout<<"The top data of stack: "<<e<<endl;
}
7 顺序队列的表示和实现
7.1 顺序表的初始化
编程思想:
一:分配空间
二:判断是否分配成功(!Q.base)
三:成功则将头指针和尾指针置为0,失败则exit
7.2 求循环队列长度
编程思想:
一:返回(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE
ps:注意Q.rear不到循环最后不储存数据
7.3 循环队列入队
编程思想:
一:判断队列是否为已满
二:已满则返回ERROR,未满则进行(三)
三:将元素插入队尾,队尾指针加一
7.4 出队
编程思想:
一:判断队列是否为空
二:空则返回ERROR,未空则进行(三)
三:将队头数据保存下来,队头指针加1
7.5 取循环队列队头元素
编程思想:
一:判断栈是否为空
二:为空则返回ERROR,不为空则返回队头元素,队头指针不变
7.6 代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define ERROR 1
#define OK 0
#define MAXSIZE 5
using namespace std;
typedef int Status;
typedef int QElemType;
typedef struct{
QElemType *base;
int front;
int rear;
}SqQueue;
/* 初始化 */
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXSIZE];
if(!Q.base) exit(ERROR);
Q.front=Q.rear=0;
return OK;
}
/* 求循环队列长度 */
int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; //有数据的节点数(因为Q.rear不存数据且下标从零开始,所以未进行循环时,length=Q.rear
} //当进行循环时,由于rear和front同步[出队一个即front+1,则多出个位置给rear即rear+1])
//所以循环时Q.rear-Q.front
/* 循环队列入队 */
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1)%MAXSIZE==Q.front) return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXSIZE;
return OK;
}
/* 循环队列出队 */
Status DeQueue(SqQueue &Q,QElemType &e){
if(Q.rear==Q.front) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXSIZE;
return OK;
}
/* 取循环队列队头元素 */
QElemType GetHead(SqQueue &Q,QElemType &e){
if(Q.rear==Q.front) return ERROR;
return Q.base[Q.front];
}
/* 存入数据 */
Status StoreData(SqQueue &Q){
int num,i;
cout<<"Please input the num of data:";
cin>>num;
cout<<"num:"<<num<<"\t"<<"size:"<<num+1<<endl;
num=num+1;
if(num>MAXSIZE) exit(ERROR);
cout<<"Please input data:"<<endl;
for(i=0;i<num-1;i++){
cin>>Q.base[Q.rear];
Q.rear=(Q.rear+1)%MAXSIZE;
}
return OK;
}
/* 输出 */
Status OutPut(SqQueue Q){
if(Q.rear==Q.front) return ERROR;
cout<<"The data of Queue:"<<endl;
while(Q.front%MAXSIZE!=Q.rear){
cout<<Q.base[Q.front]<<" ";
Q.front++;
}
cout<<"\n";
return OK;
}
/* 主函数 */
Status main(){
cout<<"MAXSIZE:5,So the num you input must <5.The num should be smaller if you wat to EnQueue."<<endl;
QElemType e;
SqQueue Q;
InitQueue(Q);
StoreData(Q);
OutPut(Q);
cout<<"Please input EnQueue data:";
cin>>e;
EnQueue(Q,e);
OutPut(Q);
GetHead(Q,e);
cout<<"The head data:"<<e<<endl;
DeQueue(Q,e);
OutPut(Q);
cout<<"Please input EnQueue data:";
cin>>e;
EnQueue(Q,e);
OutPut(Q);
}
8 队列的链式表示和实现
8.1 初始化
编程思想:
一:生成新节点做为头节点,队头队尾指针指向此节点
二:头节点的指针域置为NULL
8.2 入队
编程思想:
一:创建新节点,并赋值,将指针域置为NULL
二:在队尾插入,并移动Q.rear;
8.3 出队
编程思想:
一:判断队是否为空
二:为空则返回ERROR,不为空则进行(三)步骤
三:保存队头元素的值,修改头节点指针域,如果是最后一个元素被删,则对为指针指向头指针,删除头指针
8.4 取链队的队头元素
编程思想:
一:判断队列是否为空,不为空进行(二)
二:返回队头元素的值
8.5 代码
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define ERROR 1
#define OK 0
#define MAXSIZE 5
using namespace std;
typedef int Status;
typedef int QElemType;
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
/* 初始化 */
Status InitQueue(LinkQueue &Q){
Q.rear=new QNode;
Q.front=Q.rear;
Q.rear->next=NULL;
return OK;
}
/* 入队 */
Status EnQueue(LinkQueue &Q){
QueuePtr p;
p=new QNode;
p->next=NULL;
cout<<"Please input EnQueue data:";
cin>>p->data;
Q.rear->next=p;
Q.rear=p;
return OK;
}
/* 出队 */
Status DeQueue(LinkQueue &Q,QElemType &e){
QueuePtr p;
if(Q.front==Q.rear) return ERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(p==Q.rear) Q.front=Q.rear;
delete p;
return OK;
}
/* 取链队的队头元素 */
QElemType GetHead(LinkQueue Q){
if(Q.front!=Q.rear) return Q.front->next->data;
else return ERROR;
}
/* 存储数据 */
Status StoreData(LinkQueue &Q){
QueuePtr p;
int num,i;
cout<<"Please input the num of the data:";
cin>>num;
cout<<"Please input data:"<<endl;
for(i=0;i<num;i++){
p=new QNode;
p->next=NULL;
cin>>p->data;
Q.rear->next=p;
Q.rear=p;
}
return OK;
}
/* 输出 */
Status OutPut(LinkQueue Q){
if(Q.front==Q.rear) exit(ERROR);
cout<<"The data of queue:"<<endl;
Q.front=Q.front->next;
while(Q.front){
cout<<Q.front->data<<" ";
Q.front=Q.front->next;
}
cout<<"\n";
return OK;
}
/* 主函数 */
int main(){
QElemType e;
LinkQueue Q;
InitQueue(Q);
StoreData(Q);
OutPut(Q);
EnQueue(Q);
OutPut(Q);
DeQueue(Q,e);
OutPut(Q);
e=GetHead(Q);
cout<<"The head data:"<<e<<endl;
}
9 栈与队列的应用
9.1 数制的转换
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define OK 0
#define ERROR 1
#define MAXSIZE 100
using namespace std;
typedef int SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
/* 顺序栈的初始化 */
Status InitStack(SqStack &S){
S.base=new SElemType[MAXSIZE];
if(!S.base) exit(ERROR);
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
/* 入栈 */
Status Push(SqStack &S,SElemType e){
if(S.top-S.base==S.stacksize) return ERROR; //值得注意的是S.top-S.base得出来的是元素空间个数
*S.top++=e; //S.top不储存数据
return OK;
}
/* 出栈 */
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
/* 进制转换 */
void Conversion(int N,SqStack S){
SElemType e;
while(N){
Push(S,N%8);
N=N/8;
}
cout<<"After change:";
while(S.base!=S.top){
Pop(S,e);
cout<<e;
}
}
/* 主函数 */
int main(){
SElemType N;
SqStack S;
InitStack(S);
cout<<"Please input the number you need change:";
cin>>N;
Conversion(N,S);
}
9.2 括号匹配
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define OK 0
#define ERROR 1
#define ture 1
#define false 0
#define MAXSIZE 100
using namespace std;
typedef int SElemType;
typedef int Status;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize;
}SqStack;
/* 顺序栈的初始化 */
Status InitStack(SqStack &S){
S.base=new SElemType[MAXSIZE];
if(!S.base) exit(ERROR);
S.top=S.base;
S.stacksize=MAXSIZE;
return OK;
}
/* 入栈 */
Status Push(SqStack &S,SElemType e){
if(S.top-S.base==S.stacksize) return ERROR; //值得注意的是S.top-S.base得出来的是元素空间个数
*S.top++=e; //S.top不储存数据
return OK;
}
/* 出栈 */
Status Pop(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e=*--S.top;
return OK;
}
/* 取栈顶元素 */
SElemType GetTop(SqStack S){
if(S.top==S.base) return ERROR;
return *(S.top-1);
}
/* 存储数据 */
Status StoreData(SqStack &S){
int num,i;
if(S.base!=S.top) return ERROR;
else{
cout<<"Please input the num of data:";
cin>>num;
cout<<"Please input the data:"<<endl;
for(i=0;i<num;i++){
cin>>S.base[i];
S.top++;
}
}
return OK;
}
/* 括号匹配 */
Status Matching(SqStack S){
int flag=1,x;
char ch;
while(ch!='#'&&flag){
switch(ch){
case '[':
case '(':
Push(S,ch);
break;
case ')':
if(GetTop(S)=='(')
Pop(S,x);
else flag=0;break;
case ']':
if(GetTop(S)=='[')
Pop(S,x);
else flag=0;break;
}
cin>>ch;
}
if(S.top==S.base&&flag) return ture;
else return false;
}
/* 主函数 */
int main(){
SElemType e;
SqStack S;
InitStack(S);
cout<<Matching(S);
}
10 栈与队列作业
10.1 回文
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define ERROR 1
#define OK 0
#define MAXSIZE 100
using namespace std;
typedef int Status;
typedef char QElemType;
typedef struct{
QElemType *base;
int front;
int rear;
}SqQueue;
/* 初始化 */
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXSIZE];
if(!Q.base) exit(ERROR);
Q.front=Q.rear=0;
return OK;
}
/* 求循环队列长度 */
int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXSIZE)%MAXSIZE; //有数据的节点数(因为Q.rear不存数据且下标从零开始,所以未进行循环时,length=Q.rear
} //当进行循环时,由于rear和front同步[出队一个即front+1,则多出个位置给rear即rear+1])
//所以循环时Q.rear-Q.front
/* 存入数据 */
Status StoreData(SqQueue &Q){
int num,i;
cout<<"Please input data:"<<endl;
while(1){
Q.base[Q.rear]=getchar();
if(Q.base[Q.rear]=='\n') break;
Q.rear=(Q.rear+1)%MAXSIZE;
}
return OK;
}
/* 输出 */
Status OutPut(SqQueue Q){
if(Q.rear==Q.front) return ERROR;
cout<<"The data of Queue:"<<endl;
while(Q.front%MAXSIZE!=Q.rear){
cout<<Q.base[Q.front]<<" ";
Q.front++;
}
cout<<"\n";
return OK;
}
Status HuiWen(SqQueue Q){
int flag=1;
int Length=QueueLength(Q);
while(Q.front!=Length/2){
if(Q.base[Q.front]!=Q.base[Q.rear-1]) flag=0;
Q.front++;
Q.rear--;
}
return flag;
}
/* 主函数 */
Status main(){
QElemType e;
SqQueue Q;
InitQueue(Q);
StoreData(Q);
OutPut(Q);
cout<<"Length:"<<QueueLength(Q)<<endl;
cout<<"result:"<<HuiWen(Q);
}
10.2 队列逆置
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define ERROR 1
#define OK 0
#define MAXSIZE 100
using namespace std;
typedef int Status;
typedef int QElemType;
typedef struct{
QElemType *base;
int front;
int rear;
}SqQueue;
/* 初始化 */
Status InitQueue(SqQueue &Q){
Q.base=new QElemType[MAXSIZE];
if(!Q.base) exit(ERROR);
Q.front=Q.rear=0;
return OK;
}
/* 存储数据 */
Status StoreData(SqQueue &Q){
int num,i;
cout<<"Please input data:"<<endl;
do{
cin>>Q.base[Q.rear];
Q.rear=(Q.rear+1)%MAXSIZE;
}
while(getchar()!='\n');
return OK;
}
/* 输出 */
Status OutPut(SqQueue Q){
if(Q.rear==Q.front) return ERROR;
cout<<"The data of Queue:"<<endl;
while(Q.front%MAXSIZE!=Q.rear){
cout<<Q.base[Q.front]<<" ";
Q.front++;
}
cout<<"\n";
return OK;
}
/* 队列逆置 */
Status Reverse(SqQueue &Q){
int p,q,r;
q=Q.front;
p=Q.rear-1;
if(Q.front==Q.rear) exit(ERROR);
while(p-q>=0){
r=Q.base[p];
Q.base[p]=Q.base[q];
Q.base[q]=r;
p--;
q++;
}
return OK;
}
/* 主函数 */
Status main(){
QElemType e;
SqQueue Q;
InitQueue(Q);
StoreData(Q);
OutPut(Q);
Reverse(Q);
cout<<"After reverse:"<<endl;
OutPut(Q);
}