数据结构基本代码汇总


一、线性表

1.顺序表的定义
#define Maxsize 50
typedef struct{
	ElemType data[Maxsize];
	int length;
}SqList;

动态分配下的顺序表(不常考)
#define InitSize 100
typedef struct{
	ElemType *data;
	int MaxSize,length;
}SqList;
L.data=(ElemType*)malloc(sizeof(ElemType)*InitSize); 

2.顺序表的基本操作

//在第i个位置插入
bool ListInsert(SqList &L,int i,ElemType e){
	if(i<1||i>L.length+1) return false;
	if(L.length>=Maxsize) return false;
	for(int j=L.length;j>=i;j--){
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
}

//在第i个位置删除
bool ListDelete(SqList &L,int i,ElemType &e){
	if(i<1||i>L.length) return false;
	for(int j=i-1;j<L.length;j++){
		L.data[j]=L.data[j+1];
	}
	L.length--;
	return true;
}

//按值查找(顺序查找)
int LocateElem(Sqlist L,ElemType e){
	for(int i=0;i<L.length;i++){
		if(L.data[i]==e){
			return i+1;
		}
	}
	return 0;
}

2.线性表的链式表示

1.单链表定义
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode,*LinkList;

单链表的基本操作

1.头插法建立单链表
LinkList Insert_head(LinkList &L){
	LNode *s;
	int x;
	L=(LinkList)malloc(sizeof(LinkNode));
	scanf("%d",&x);
	while(x!=9999){
		s=(LinkNode*)malloc(sizeof(LinkNode));
		s->data=x;
		s->next=L->next;
		L->next=s;
		scanf("%d",&x);
	}
	return L;
}

2.尾插法建立单链表
LinkList Insert_tail(LinkList &L){
	LinkNode *s,*r;
	int x;
	L=(LinkList)malloc(sizeof(LinkNode));
	r=L;
	scanf("%d",&x);
	while(x!=9999){
		s=(LinkNode*)malloc(sizeof(LinkNode));
		s->data=x;
		r->next=s;
		r=s;
		scanf("%d",&x);
	}
	r->next=NULL;
	return L;
}

3.按序号查找节点
LinkNode *Findvalue(LinkList L,int i){
	int j=1;
	LinkNode *p=L->next;
	if(i==0) return L;
	if(i<1) return NULL;
	while(p&&j<i){
		p=p->next;
		j++;
	}
	return p;
}

4.按值查找节点
LinkNode *Getvalue(LinkList L,ElemType e){
	LinkNode *p=L->next;
	while(p&&p->data!=e){
		p=p->next;
	}
	return p;
}

5.插入节点(插入值为x的节点到第i个位置)
void Insertvalue(LinkList &L,int i,ElemType e){
	LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
	s->data=e;
	int j=1;
	LinkNode *p=L->next;
	while(p&&j<i-1){
		p=p->next;
		j++;
	}
	s->next=p->next;
	p->next=s;
	return ;
}

6.删除第i个节点
void Deletei(LinkList &L,int i){
	int j=1;
	LinkNode *p=L->next;
	while(p&&j<i-1){
		p=p->next;
		j++;
	}
	LinkNode *s=p->next;
	p->next=s->next;
	free(s);
	return ;
}

双链表

1.定义
typedef struct DNode{
	ElemType data;
	struct DNode *prior,*next;
}DNode,*DLinkList;

2.插入
	s->next=p->next;
	p->next->prior=s;
	p->next=s;
	s->prior=p;

3.删除
p->next=s->next;
s->next->prior=p;
free(s);

静态链表

1.定义
#define MaxSize 50
typedef struct{
	ElemType data;
	int next;
}SLinkList[MaxSize];

二、栈

顺序栈(大题中常用此物理结构)

1.定义
#define MaxSize 50
typedef struct{
	ElemType data[MaxSize];
	int top;
}SqStack;

2.初始化
void InitStack(SqStack &S){
	S.top=-1;
}

3.判断栈为空
bool StackEmpty(SqStack S){
	if(S.top==-1)
		return true;
	else
		return false;
}

4.进栈
bool Push(SqStack &S,ElemType x){
	if(S.top==MaxSize-1) return false;
	S.data[++S.top]=x;
	return true;
}

5.出栈
bool Pop(SqStack &S,ElemType &x){
	if(S.top==-1) return false;
	x=S.data[S.top--];
	return true;
}

6.读栈顶元素
bool GetTop(SqStack &S,ElemType &x){
	if(S.top==-1) return false;
	x=S.data[S.top];
	return true;
}

链式栈

1.定义
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}*LiStack;


三、队列

顺序循环队列

1.定义
#define MaxSize 60
typedef struct{
	ElemType data[MaxSize];
	int front,rear;
}SqQueue;

2.初始化
void InitQueue(SqQueue &Q){
	Q.front=Q.rear=0;
}

3,判断队空
bool QueueEmpty(SqQueue Q){
	if(Q.front==Q.rear)
		return true;
	else
		return false;
}

4.入队
bool EnQueue(SqQueue &Q,ElemType x){
	if((Q.rear+1)%MaxSize==Q.front){
		return false;
	}
	Q.data[Q.rear]=x;
	Q.rear=(Q.rear+1)%MaxSize;
	return true;
}

5.出队
bool DeQueue(SqQueue &Q,ElemType &x){
	if(Q.rear==Q.front){
		return false;
	}
	x=Q.data[Q.front];
	Q.front=(Q.front+1)%MaxSize;
	return true;
}

链式队列

1.定义
typedef struct LinkNode{
	ElemType data;
	struct LinkNode *next;
}LinkNode;
typedef struct{
	LinkNode *front,*rear;
}LinkQueue;

2.初始化
void InitQueue(LinkQueue &Q){
	Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next=NULL;
}

3.判断队空
bool isEmpty(LinkQueue Q){
	if(Q.front==Q.rear)
		return true;
	else
		return false;
}

4.入队(链队无须判断队满)
void EnQueue(LinkQueue &Q,ElemType x){
	LinkNode *s=(LinkNode*)malloc(sizeof(LinkNode));
	s->data=x;s->next=NULL;
	Q.rear->next=s;
	Q.rear=s;
}

5.出队
bool DeQueue(LinkQueue &Q,ElemType &x){
	if(Q.rear==Q.front){
		return false;
	}
	LinkNode *p=Q.front->next;
	x=p->data;
	Q.front->next=p->next;
	if(Q.rear==p){
		Q.rear=Q.front;
	}
	free(p);
	return true;
}

四、串

顺序存储

#define MLen 255
typedef struct{
	char ch[MLen];
	int length;
}SString;

堆分配存储(动态分配)

typedef struct{
	char *ch;
	int length;
}HString;

简单的模式匹配算法

int index(SString s,SString t){
	int i=1,j=1;
	while(i<=s.length&&j<=t.length){
		if(s.ch[i]==t.ch[j]){
			i++,j++;
		}else{
			i=i-j+2;
			j=1;
		}
	}
	if(j>t.length){
		return i-t.length;
	}else{
		return 0;
	}
}

KMP算法

void get_next(String s,int next[]){
	int i=1,j=0;
	next[1]=0;
	while(i<t.length){
		if(j==0||t.ch[i]==t.ch[j]){
			i++,j++;
			next[i]=j;
		}else{
			j=next[j];
		}
	}
}
int index_kmp(String s,String t,int next[]){
	int i=1,j=1;
	while(i<=s.length&&j<=t.length){
		if(j==0||s.ch[i]==t.ch[j]){
			j++,i++;
		}else{
			j=next[j];
		}
		if(j>t.length){
			return i-t.length;
		}else
			return 0;
	}
}

//优化
void get_nextval(String t,int nextval[]){
	int i=1,j=0;
	nextval[1]=0;
	while(i<t.length){
		if(j==0||t.ch[i]==t.ch[j]){
			i++,j++;
			if(t.ch[i]!=t.ch[j]) 
				nextval[i]=j;
			else 
				nextval[i]=nextval[j];
		}else{
			j=nextval[j];
		}
	}
}

五、树与二叉树

二叉树

1.定义
typedef struct BiNode{
	int data;
	struct BiNode *lchild,*rchild;
}BiNode,*BiTree; 

2.先序遍历
void PreOrder(BiTree T){
	if(T!=NULL){
		visit(T);
		PreOrder(T->lchild);
		PreOrder(T->rchild);
	}
}

3.1先序遍历的非递归算法(栈)
void PreOrder_f(BiTree T){
	InitStack(S);
	BiTree p=T;
	while(p||!isEmpty(S)){
		if(p){
			visit(p);
			Push(S,p);
			p=p->lchild;
		}else{
			Pop(S,p);
			p=p->rchild;
		}
	}
}

3.2中序遍历的非递归算法//与先序类似
void InOrder(BiTree T){
	InitStack(S);
	BiTree p=T;
	while(p||!IsEmpty(S)){
		if(p){
			Push(S,p);
			p=p->lchild;
		}else{
			Pop(S,p);
			visit(p);
			p=p->rchild;
		}
	}
}

3.3后序遍历的非递归算法(难)
void PostOrder_f(BiTree T){
	InitStack(S);
	BiTree p=T;
	BiNode *r=NULL;
	while(p||!isEmpty(S)){
		if(p){
			Push(S,p);
			p=p->lchild;
		}else{
			GetTop(S,p);
			if(p->rchild&&p->rchild!=r){
				p=p->rchild;
			}else{
				Pop(S,p);
				visit(p);
				r=p;
				p=NULL;
			}	
		}
	}
}

4.层次遍历(队列)
void LevelOrder(BiTree T){
	InitQueue(Q);
	BiTree p;
	EnQueue(Q,T);
	while(!IsEmpty(Q)){
		DeQueue(Q,p);
		visit(p);
		if(p->lchild!=NULL){
			EnQueue(Q,p->lchild);
		}
		if(p->rchild!=NULL){
			EnQueue(Q,p->rchild);
		}
	}
}

线索二叉树

1.定义
typedef struct ThreadNode{
	int data;
	int ltag,rtag;
	struct ThreadNode *lchild,*rchild;
}ThreadNode,*ThreadTree;

2.中序线索化建线索二叉树
void InThread(ThreadTree &p,ThreadTree &pre){
	if(p!=NULL){
		InThread(p->lchild,pre);
		if(p->lchild==NULL){
			p->lchild=pre;
			p->ltag=1;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->rchild=p;
			pre->rtag=1;
		}
		pre=p;
		InThread(p->rchild,pre);
	}
}
void CreateInThread(ThreadTree T){
	ThreadTree pre=NULL;
	if(T!=NULL){
		InThread(T,pre);
		pre->rchild=NULL;
		pre->rtag=1;
	}
}

3.先序线索化建线索二叉树(防转圈)
void PreThread(ThreadTree &p,ThreadTree &pre){
	if(p!=NULL){
		if(p->lchild==NULL){
			p->lchild=pre;
			p->ltag=1;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->rchild=p;
			pre->rtag=1;
		}
		pre=p;
		if(p->ltag==0)//防转圈,确保左子树还没有被线索化
			PreThread(p->lchild,pre);
		PreThread(p->rchild,pre);
	}
}
void CreatePreThread(ThreadTree T){
	ThreadTree pre=NULL;
	if(T!=NULL){
		PreThread(T,pre);
		pre->rchild=NULL;
		pre->rtag=1;
	}
}

4.后序线索化建线索二叉树
void CreatePostThread(ThreadTree T){
	ThreadTree pre=NULL;
	if(T!=NULL){
		PostThread(T,pre);
		pre->rchild=NULL;
		pre->rtag=1;
	}
}
void PostThread(ThreadTree &p,ThreadTree &pre){
	if(p!=NULL){
		PostThread(p->lchild,pre);
		PostThread(p->rchild,pre);
		if(p->lchild==NULL){
			p->lchild=pre;
			p->ltag=1;
		}
		if(pre!=NULL&&pre->rchild==NULL){
			pre->rchild=p;
			pre->rtag=1;
		}
		pre=p;
	}	
}

5.中序线索二叉树的遍历
(1)求中序序列下第一个结点
ThreadNode *Firstnode(ThreadNode *p){
	while(p->ltag==0) p=p->lchild;
	return p;
}2)求结点p的后继
ThreadNode *Nextnode(ThreadNode *p){
	if(p->rtag==1) return p->rchild;
	return Firstnode(p->rchild);
}3)中序遍历中序线索二叉树
void Inorder(ThreadNode *T){
	for(ThreadNode *p=Firstnode(p);p!=NULL;p=Nextnode(p))
		visit(p);
}

1.定义
(1)双亲表示法
#define MAX_TREE 100
typedef struct{
	ElemType data;
	int parent;
}PTNode;
typedef struct{
	PTNode nodes[MAX_TREE];
	int n;
}PTree;2)孩子兄弟表示法
typedef struct CSNode{
	ElemType data;
	struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;3)孩子表示法(将每个结点的孩子都用单链表链接起来形成一个线性结构,n个结点有n个孩子链表)

并查集

1.定义
#define SIZE 100
int UFSets[SIZE];

2.初始化
void Init(int S[]){
	for(int i=0;i<size;i++)
		S[i]=-1;
}

3.合并root1和root2到一个分支上
void Union(int S[],int root1,int root2){
	S[root2]=root1;
}

4.找x的祖先(根节点)
int Find(int S[],int x){
	while(S[x]>0){
		x=S[x];
	}
	return x;
}

六、图

邻接矩阵

1.定义
#define MaxNode 100
typedef char VerType;
typedef int EdgeType;
typedef struct{
	EdgeType Edge[MaxNode][MaxNode];
	VerType Vex[MaxNode];
	int vernum,edgenum;
}MGraph;

邻接表

1.定义
typedef struct ALGraph{
	AdjList v;//表示一个顶点表数组
	int vexnum,arcnum;
}ALGraph;
typedef struct VNode{//顶点表数组 
	char data;//每个节点的名字 
	ArcNode *first;
}VNode,AdjList[MaxSize];
typedef struct ArcNode{
	int adjnum;//弧所指向的结点的编号(与顶点表数组对应) 
	struct ArcNode *next;
}ArcNode;

从图的邻接表表示转换成邻接矩阵

void Convert(ALGraph G1,MGraph &G2){
	G2.edgenum=G1.arcnum;
	G2.vexnum=G1.vexnum;
	for(int i=0;i<G1.vexnum;i++){//初始化G2
		for(int j=0;j<G1.vexnum;j++){
			G2.Edge[i][j]=0;
		}
	}
	for(int i=0;i<G1.vexnum;i++){
		ArcNode *p=G1.vertices[i].first;
		while(p){
			int j=p->adjnum;
			G2.Edge[i][j]=1;
			p=p->next;
		}
	}
}

从图的邻接矩阵转化为邻接表

void convert(MGraph G1,ALGraph &G2){
	G2.arcnum=G1.edgenum;
	G2.vexnum=G1.vexnum;
	for(int i=0;i<G1.vexnum;i++){
		G2.vertices[i].first=NULL;
	}
	for(int i=0;i<G1.vexnum;i++){
		for(int j=0;j<G1.vexnum;j++){
			if(G1.Edge[i][j]){
				ArcNode *p=(ArcNode*)malloc(sizeof(ArcNode));
				p->adjnum=j;
				p->next=G2.vertices[i].first;
				G2.vertices[i].first=p;
			}
		}
	}
} 

图的基本操作

1.NextNeighbor(MGraph &G,int x,int y)
//邻接矩阵
#define maxWeight 0x3f3f3f3f
int NextNeighbor(MGraph &G,int x,int y){
	if(x!=-1&&y!=-1){
		for(int col=y+1;col<G.vexnum;col++){
			if(G.Edge[x][col]>0&&G.Edge[x][col]<maxWeight)
				return col;
		}
	}
	return -1;
}

//邻接表
int NextNeighbor(ALGraph &G,int x,int y){
	if(x!=-1){
		ArcNode *p=G.vertices[x].first;
		while(p!=NULL&&p->data!=y)
			p=p->next;
		if(p!=NULL&&p->next!=NULL)
			return p->next->data;
	}
	return -1;
}

广度优先搜索BFS(队列实现)

int vis[MaxSize];
void BFSOrder(Graph G){
	for(int i=0;i<G.vexnum;i++){
		vis[i]=0;
	}
	InitQueue(Q);
	for(int i=0;i<G.vexnum;i++){//预防非连通图的情况
		if(!vis[i])
			BFS(G,i);
	}
}
void BFS(Graph G,int i){
	vis[i]=1;
	EnQueue(Q,i);
	while(!isEmpty(Q)){
		DeQueue(Q,v);
		for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
			if(!vis[w]){
				vis[w]=1;
				EnQueue(Q,w);
			}
		}
	}
}

BFS求单源最短路(无权值)

void BFS_MIN(Graph G,int u){//求u到图中其余顶点的最短路径 
	for(int i=0;i<G.vexnum;i++){
		d[i]=-1;
	}
	vis[u]=1;d[u]=0;
	EnQueue(Q,u);
	while(!isEmpty(Q)){
		DeQueue(Q,u);
		for(w=FirstNeighbor(Q,u);w>=0;w=NextNeighbor(Q,u,w)){
			if(!vis[w]){
				vis[w]=1;
				d[w]=d[u]+1;//
				EnQueue(Q,w);
			}
		}
	}
} 

深度优先搜索DFS

int vis[MaxSize];
void DFSOrder(Graph G){//和bfs一模一样
	for(int i=0;i<G.vexnum;i++){
		vis[i]=0;
	}
	for(int i=0;i<G.vexnum;i++){
		if(!vis[i]){
			DFS(G,i);
		}
	}
} 
void DFS(Graph G,int v){
	vis[v]=1;
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
		if(!vis[w]){
			DFS(G,w);//走一条中国特色社会主义道路
		}
	}
}

用dfs判断无向图是否是树

int vis[MaxSize];
bool pd_Tree(Graph G){
	int vnum=1,anum=0;
	for(int i=0;i<G.vexnum;i++){
		vis[i]=0;
	}
	DFS(G,0,vnum,anum);
	if(vnum==G.vexnum&&2*(vnum-1)=anum)
		return 1;
	else 
		return 0;
}
void DFS(Graph G,int v,int &vnum,int &anum){
	vis[v]=1;
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
		if(!vis[w]){
			vnum++;
			anum++;
			DFS(G,w,vnum,anum);
		}
	}
}

dfs的非递归算法(用栈实现,与bfs基本一样)

int vis[MaxSize];
void DFS_f(Graph G,int v){//从v结点开始遍历,前提是这个图是连通图 
	int w;
	InitStack(S);
	for(i=0;i<G.vexnum;i++){
		vis[i]=0;
	}
	Push(S,v);vis[v]=1;
	while(!isEmpty(S)){
		Pop(S,p);
		visit(p);
		for(w=FirstNeighbor(G,p);w>=0;w=NextNeighbor(G,p,w)){
			if(!vis[w]){
				Push(S,w);
				vis[w]=1;
			}
		}
	}
}

用dfs判断是否存在vi到vj的路径

int vis[MaxSize]={0};
void DFS(ALGraph G,int i,int j,bool &can_reach){
	if(i==j){
 		can_reach=true;
 		return;
	}
	vis[i]=1;
	for(int p=FirstNeighbor(G,i);p>=0;p=NextNeighbor(G,i,p)){
	 	if(!vis[p]&&!can_reach)
	 		DFS(G,p,j,can_reach);
	}
}

用bfs判断是否存在vi到vj的路径

int vis[MaxSize]={0};
int BFS(ALGraph G,int i,int j){
	InitQueue(Q);
	EnQueue(i);
	while(!isEmpty(Q)){
		DeQueue(Q,p);
		vis[p]=1;
		if(p==j) return 1;
		for(int w=FirstNeighbor(G,p);w>=0;w=NextNeighbor(G,p,w)){
			if(w==j) return 1;
			if(!vis[w]){
				vis[w]=1;
				EnQueue(Q,w);
			}
		}
	}
	return 0;
}

vi到vj所有简单路径

void FindPath(ALGraph &G,int u,int v,int path[],int d){
	d++;
	path[d]=u;
	vis[u]=1;
	if(u==v){
		print(path[]);
	}
	ArcNode *p;
	p=G->AdjList[u].firstarc;
	while(p){
		w=p->adjnum;
		if(!vis[w])
			FindPath(G,w,v,path,d);
		p=p->next;
	}
	vis[u]=0;
}

最小生成树

1.Prim算法
int getSum(MGraph &G,int *prims){
	int sum=0;
	for(int i=1;i<G.vexnum;i++){
		int min=39999;
		for(int j=0;j<i;j++){
			if(G.Edge[prims[j]][prims[i]]<min){
				min=G.Edge[prims[j]][prims[i]];
			}
		}
		sum+=min;
	}
	return sum;
}
void prim(MGraph &G,int start){//邻接矩阵实现 
	int prims[MaxSize];
	int lowCost[MaxSize];
	int min,k,index=0;		
	lowCost[start]=0;//自己到自己的距离为0 
	prims[index++]=start;
	for(int i=0;i<G.vexnum;i++){
		lowCost[i]=G.Edge[start][i];//将所有连接顶点的边的权值存入 
	}
	for(int i=0;i<G.vexnum;i++){
		if(start==i) continue;
		min=39999;
		for(int j=0;j<G.vexnum;j++){
			if(lowCost[j]!=0&&lowCost[j]<min){
				min=lowCost[j];
				k=j;
			}
		}
		prims[index++]=k;
		lowCost[k]=0;//将当前选中的顶点置为已访问 
		for(int j=0;j<G.vexnum;j++){
			if(lowCost[j]&&G.Edge[k][j]<lowCost[j]){
				lowCost[j]=G.Edge[k][j];
			}
		}
		printf("%d",getSum(G,prims));
		for(int i=0;i<G.vexnum;i++){
			printf("%c",G.Vex[prims[i]]);
		}
	}
}


拓扑排序

bool TopoSort(Graph G){
	InitStack(S);
	for(int i=0;i<G.vexnum;i++){
		if(indegree[i]==0)
			Push(S,i);
	}
	int count=0;
	while(!isEmpty(S)){
		Pop(S,i);
		print[count++]=i;
		for(p=G.adjList[i].firstarc;p;p=p->next){
			v=p->adjnum;
			if(!(--indegree[v]))
				Push(S,v);
		}
	}
	if(count<G.vexnum) return false;
	else return true;
}

DFS实现拓扑排序

int vis[MaxSize]={0};
void DFStopo(Graph G){
	time=0;
	for(v=0;v<G.vexnum;v++){
		if(!vis[v])
			DFS(G,v);
	}
}
void DFS(Graph G,int v){
	vis[v]=1;
	visit(v);
	for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
		if(!vis[w]){
			DFS(G,w);
		}
	}
	time=time+1;
	finishTime[v]=time;
}

七、查找

顺序查找

typedef struct{
	Elemtype elem[MaxSize];
	int len;
}STable;
int search(STable ST,Elemtype key){
	ST.elem[0]=key;//哨兵
	int i;
	for(i=ST.len;ST.elem[i]!=key;i--);
	return i;
} 

折半查找

int binary_search(STable L,Elemtype key){
	int low=0,high=L.len-1,mid;
	while(low<=high){
		mid=(low+high)/2;
		if(L.elem[mid]==key)
			return mid;
		else if(L.elem[mid]>key)
			high=mid-1;
		else
			low=mid+1;
	}
	return -1;
}

//递归写法
int binary_search1(STable L,Elemtype key,int low,int high){
	if(low>high)
		return 0;
	mid=(low+high)/2;
	if(key>ST.elem[mid])
		binary_search1(L,key,mid+1,high);
	else if(key<ST.elem[mid])
		binary_search1(L,key,low,mid-1);
	else
		return mid; 
} 

顺序检索算法(找到指定结点后与前驱结点交换)

//顺序表存储
int seqsrch(STable L,Elemtype key){
	int i=0;
	while(L.elem[i]!=k&&i<n)
		i++;
	if(i<n&&i>0){
		Elemtype t=L.elem[i];
		L.elem[i]=L.elem[i-1];
		L.elem[i-1]=t;
		return --i;
	}
	else
		return -1;
}

//链表存储
typedef struct LNode{
	int data;
	struct LNode *next;
}LNode,*LinkList;
int seqsrch1(LinkList &L,int key){
	LNode *p=L;
	int i=1;
	if(p->data==key) return i;//第一个结点就是指定结点,无需与前面交换 
	while(p->next!=NULL){
		if(p->next->data==key){
			int t=p->next->data;
			p->next->data=p->data;
			p->data=t;
			return i;
		}
		i++;
	}
	return -1;
}

二叉排序树

1.查找
BiNode *BST_Search(BiTree T,Elemtype key){
	while(T!=NULL&&key!=T->data){
		if(key<T->data) T=T->lchild;
		else T=T->rchild;
	}
	return T;
}

2.插入
int BST_Insert(BiTree &T,int k){
	if(T==NULL){
		T=(BiTree)malloc(sizeof(BiNode));
		T->data=k;
		T->lchild=T->rchild=NULL;
		return 1;
	}
	else if(k==T->data)
		return 0;
	else if(k<T->data)
		return BST_Insert(T->lchild,k);
	else 
		return BST_Insert(T->rchild,k);
}

3.构造
void Creat_BST(BiTree &T,int data[],int n){
	T=NULL;
	int i=0;
	while(i<n){
		BST_Insert(T,data[i]);
		i++;
	}
}

4.判断是否是二叉排序树
int pd=-32767;
int JudgeBST(BiTree bt){
	int b1,b2;
	if(bt==NULL) return 1;
	else{
		b1=JudgeBST(bt->lchild);
		if(b1==0||pd>=bt->data)
			return 0;
		pd=bt->data;
		b2=JudgeBST(bt->rchild);
		return b2;
	}
}

5.求指定结点在二叉排序树中的层次
int level(BiTree bt,BiNode *p){
	int n=0;
	BiTree t=bt;
	if(bt!=NULL){
		n++;
		while(t->data!=p->data){
			if(p->data<t->data)
				t=t->lchild;
			else
				t=t->rchild;
			n++;
		}
	}
	return n;
}

6.求最小和最大的关键字(根据二叉排序树性质)
int min_key(BiNode *bt){
	while(bt->lchild!=NULL)
		bt=bt->lchild;
	return bt->data;
}
int max_key(BiNode *bt){
	while(bt->rchild!=NULL)
		bt=bt->rchild;
	return bt->data;
}

7.从大到小输出所有value不小于k的关键字
void Out_k(BiNode *bt,int k){
	if(bt==NULL) return ;
	if(bt->rchild!=NULL)
		Out_k(bt->rchild,k);
	if(bt->data>=k)
		printf("%d",bt->data);
	if(bt->lchild!=NULL)
		Out_k(bt->lchild,k);
}

8.查找第k小的元素并返回其指针
typedef struct BiNode{
	int data;
	int count;//以该节点为根的子树上的结点个数
	struct BiNode *lchild,*rchild;
}BiNode,*BiTree;
BiNode *Search_k(BiNode *t,int k){
	if(k<1||k>t->count) return NULL;
	if(t->lchild==NULL){
		if(k==1) return t;
		else return Search_k(t->rchild,k-1);
	}else{
		if(t->lchild->count==k-1) 
			return t;
		if(t->lchild->count>k-1) 
			return Search_k(t->lchild,k);
		if(t->lchild->count<k-1)
			return Search_k(t->rchild,k-(t->lchild->count+1));
	}
}

判断是否是平衡二叉树

void Judge_AVL(BiTree bt,int &balance,int &h){
	int bl=0,br=0,hl=0,hr=0;
	if(bt==NULL){
		h=0;
		balance=1;
	}else if(bt->lchild==NULL&&bt->rchild==NULL){
		h=1;
		balance=1;
	}else{
		Judge_AVL(bt->lchild,bl,hl);
		Judge_AVL(bt->rchile,br,hr);
		h=max(hl,hr)+1;
		if(abs(hl-hr)<2)
			balance=bl&&br;
		else 
			balance=0;
	}
}

八、排序

插入排序

1.直接插入排序
void InsertSort(ElemType A[],int n){
	int i,j;
	for(i=2;i<=n;i++){
		if(A[i]<A[i-1]){
			A[0]=A[i];
			for(int j=i-1;A[0]<A[j];--j)
				A[j+1]=A[j];
			A[j+1]=A[0];
		}
	}
}

2.折半插入排序
void HalfSort(ElemType A[],int n){
	int i,j,low,high,mid;
	for(i=2;i<=n;i++){
		A[0]=A[i];
		low=1,high=i-1;
		while(low<=high){
			mid=(low+high)/2;
			if(A[mid]>A[0]) high=mid-1;
			else low=mid+1;
		}
		for(j=i-1;j>=high+1;--j)
			A[j+1]=A[j];
		A[high+1]=A[0]; 
	}
}

3.希尔排序
void ShellSort(ElemType A[],int n){
	int dk,i,j;
	for(dk=n/2;dk>=1;dk=dk/2){
		for(i=dk+1;i<=n;i++){
			if(A[i]<A[i-dk]){
				A[0]=A[i];
				for(j=i-dk;j>0&&A[0]<A[j];j-=dk)
					A[j+dk]=A[j];
				A[j+dk]=A[0];
			}
		}
	}
}

交换排序

1.冒泡排序
void BubbleSort(int A[],int n){//数组下标为0 
	int flag;
	for(int i=0;i<n-1;i++){
		flag=0;
		for(j=n-1;j>i;j--){
			if(A[j-1]>A[j]){
				swap(A[j-1],A[j]);
				flag=1;
			}
		if(!flag) return;
		}
	}
}

2.快速排序
void QuickSort(int A[],int low,int high){
	if(low<high){
		int pos=Partition(A,low,high);
		QuickSort(A,low,pos-1);
		QuickSort(A,pos+1,high);
	}
} 
int Partition(int A[],int low,int high){
	int pivot=A[low];
	while(low<high){
		while(low<high&&A[high]>=pivot)	high--;
		A[low]=A[high];
		while(low<high&&A[low]<=pivot) low++;
		A[high]=A[low];
	}
	A[low]=pivot;
	return low;
}

插入排序衍生题目

1.双向冒泡排序
void DBubbleSort(int A[],int n){//数组下标(0,n-1) 
	int low=0,high=n-1;
	int flag=1;
	while(low<high&&flag){
		flag=0;
		for(i=low;i<high;i++){
			if(a[i]>a[i+1]){
				swap(a[i],a[i+1]);
				flag=1;
			}
		}
		high--;
		for(i=high;i>low;i--){
			if(a[i]<a[i-1]){
				swap(a[i],a[i+1]);
				flag=1;
			}
		}
		low++;
	}	
}

2.奇数在前偶数在后
void MoveJiOu(int A[],int n){
	int i=0,j=n-1;
	while(i<j){
		while(i<j&&A[j]%2==0){
			j--;
		}
		while(i<j&&A[i]%2==1){
			i++;
		}
		if(i<j){
			swap(A[i],A[j]);
			i++,j--;
		}
	}
}

3.随机枢纽快排
void Partition(int A[],int low,int high){
	int ran=low+rand()%(high-low+1);
	swap(A[ran],A[low]);
	int pivot=A[low];
	while(low<high){
		while(low<high&&A[high]>=pivot) high--;
		A[low]=A[high];
		while(low<high&&A[low]<=pivot) low++;
		A[high]=A[low];
	}
	A[low]=pivot;
	return low;
}
void QuickRSort(int A[],int low,int high){
	if(low<high){
		int pos=Partition(A,low,high);
		QuickSort(A,low,pos-1);
		QuickSort(A,pos+1,high);
	}
} 

4.找第k小元素
int find_mink(int a[],int k,int low,int high){
	int pivot=a[low];
	int low_temp=low;
	int high_temp=high;
	while(low<high){
		while(low<high&&a[high]>=pivot){
			high--;
		}
		a[low]=a[high];
		while(low<high&&a[low]<=pivot){
			low++;
		}
		a[high]=a[low];
	}
	a[low]=pivot;
	if(low==k) return a[low];
	else if(low>k) 
		find_mink(a,k,low_temp,low-1);
	else
		find_mink(a,k,low+1,high_temp);
}

5.荷兰国旗问题(三色排序)
//red是0,white是1,blue是2 
void color_sort(int a[],int n){
	int cur=0,begin=0,end=n-1;
	while(cur<=end){
		if(a[cur]==0){
			swap(a[begin],a[cur]);
			cur++,begin++;
		}else if(a[cur]==2){
			swap(a[cur],a[end]);
			end--;
		}else{
			cur++;
		}
	}
}

6.将数组个数均等分成两个数组,两个数组差值最大
int setPartition(int a[],int low,int high){
	int pivot=a[low];
	while(low<high){
		while(low<high&&a[high]>=pivot) high--;
		a[low]=a[high];
		while(low<high&&a[low]<=pivot) low++;
		a[high]=a[low];
	}
	a[low]=pivot;
	return low; 
}
void QuickSort(int a[],int low,int high,int mid){
	if(low<high){
		int pos=setPartition(a,low,high);
		if(pos==mid) return;
		if(pos>mid)
			QuickSort(a,low,pos-1,mid);
		if(pos<mid)
			QuickSort(a,pos+1,high,mid);	
	}
}
int main()
{
	int a[]={};//待排序数组 
	int s1=0,s2=0;
	QuickSort(a,0,n-1,(n-1)/2);
	int i,j;
	for(i=0;i<=(n-1)/2;i++){
		s1+=a[i];
	}
	for(j=i;j<n;j++){
		s2+=a[j];
	}
	cout<<s2-s1;
	return 0;
}

选择排序

1.简单选择排序
void select_sort(int a[],int n){
	for(i=0;i<n-1;i++){
		min=i;
		for(j=i+1;j<n;j++)
			if(a[j]<A[min])	min=j;
		if(min!=i) swap(a[i],a[min]);
	}
}

2.堆排序*(难点)
void BuildMaxHeap(int a[],int len){//建大根堆 
	for(int i=len/2;i>0;i--){
		HeadAdjust(A,i,len);
	}
}
void HeadAdjust(int a[],int k,int len){
	a[0]=a[k];
	for(i=2*k;i<=len;i*=2){
		if(i<len&&a[i]<a[i+1]) i++;
		if(a[0]>=a[i]) break;
		else{
			a[k]=a[i];
			k=i;
		}
	}
	a[k]=a[0];
}
void HeapSort(int a[],int len){//数组下标(1,n) 
	BuildMaxHeap(a,len);
	for(int i=len;i>1;i--){
		swap(a[i],a[1]);
		HeadAdjust(a,1,i-1);
	}
}

选择排序拓展题目

1.单链表上进行简单选择排序
void select_sort(LinkList &L){
	LinkNode *h=L,*p,*q,*r,*s;//p是工作指针,q是p前驱
	//s是最大值指针,r是s前驱
	L=NULL;
	while(h!=NULL){
		p=s=h;q=r=NULL;
		while(p!=NULL){
			if(p->data>s->data){
				s=p;
				r=q;
			}
			q=p;
			p=p->next;
		}
		if(s==h) h=h->next;//最大值在头结点
		else r->next=s->next;
		s->next=L;
		L=s;
	}
}

2.判断小根堆
bool IsMinHeap(int a[],int len){
	if(len%2==0){//注意,结点数为偶数二叉树必有一个单分支节点 
		if(a[len/2]>a[len]) return false;//对其特判 
		for(int i=len/2-1;i>0;i--){
			if(a[i]>a[i*2]||a[i]>a[i*2+1])
				return false;
		}
	}else{
		for(int i=len/2;i>0;i--){
			if(a[i]>a[i*2]||a[i]>a[i*2+1])
				return false;
		}
	}
	return true;
}

归并排序

int *b=(int *)malloc((n+1)*sizeof(int));
void Merge(int a[],int low,int mid,int high){
	for(int k=low;k<=high;k++)
		b[k]=a[k];
	for(int i=low,j=mid+1,k=i;i<=mid&&j<=high;k++){
		if(b[i]<=b[j])
			a[k]=b[i++];
		else
			a[k]=b[j++];
	}
	while(i<=mid) a[k++]=b[i++];
	while(j<=high) a[k++]=b[j++];
} 
void MergeSort(int a[],int low,int high){
	if(low<high){
		int mid=(low+high)/2;
		MergeSort(a,low,mid);
		MergeSort(a,mid+1,high);
		Merge(a,low,mid,high);
	}
}
一些习题
1.计数排序
void CountSort(int a[],int b[],int n){
	int cnt,i,j;
	for(i=0;i<n;i++){
		for(j=0,cnt=0;j<n;j++){
			if(a[j]<a[i]) cnt++;
		}
		b[cnt]=a[i];
	}
}

2.找到无序数组最后一个元素位置(快排思想)
int Partitionk(int a[],int n){
	int low=0,high=n-1;
	int pivot=a[n-1];
	while(low<high){
		while(low<high&&a[high]>=pivot)
			high--;
		a[low]=a[high];
		while(low<high&&a[low]<=pivot)
			low++;
		a[high]=a[low];
	}
	a[low]=pivot;
	return low;
}
  • 44
    点赞
  • 511
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
问题描述:航空客运订票的业务活动包括:查询航线、客票预订和办理退票等。试设计一个航空客运订票系统,以使上述业务可以借助计算机来完成。 设计任务:通过此系统可以实现如下功能: 录入:可以录入航班情况(数据可以存储在一个数据文件中,数据结构、具体数据自定) 查询:可以查询某个航线的情况(如,输入航班号,查询起降时间,起飞抵达城市,航班票价,票价折扣,确定航班是否满仓);可以输入起飞抵达城市,查询飞机航班情况;根据旅客提出的终点站名输出下列信息:航班号、飞机号、星期几飞行,最近一天航班的日期和余票额; 订票:(订票情况可以存在一个数据文件中,结构自己设定)根据客户提出的要求(日期、航班号、订票数额)查询该航班票额情况,若尚有余额,则为客户办理订票手续,输出座位号;若已满员或余票额少于订票额,则需要重新询问客户要求。若需要,可预约登记排队等候。如果该航班已经无票,可以提供相关可选择航班; 退票:根据客户提供的情况(日期、航班、退票数额),为客户办理退票手续,然后查询该航班是否有人预约登记,首先询问排在第一的客户,若所退票额能满足他的要求,则为他办理订票手续,否则依次询问其他排队预约的客户……退票成功后修改相关数据文件。 客户资料有姓名,证件号,订票数量及航班情况,订单要有编号。 修改航班信息:当航班信息改变可以修改航班数据文件 要求:根据以上功能说明,设计航班信息,订票信息的存储结构,设计程序完成功能。 测试数据:由学生任意指定,但报告上要求写出多批数据测试结果。 实现提示:每条航线应包含的信息有:终点站名、航班号、飞机号、飞行日期(星期几)、乘员定额、余票额、已订票的客户名单(包括姓名、订票额、座位号)和预约登记的客户名单(包括日期、姓名、所需票额)。这最后两项显然是一个线性表和一个队列。为查找方便、已订票客户的线性表应按客户姓名有序,并且,为插入和删除方便,应以链表作存储结构。由于预约人数无法预料,队列也应以链表作存储结构。整个系统需汇总各条航线的情况登录在一张线性表上,由于航线基本不变,可采用顺序存储结构,并按航班有序或按终点站名有序。每条航线是这张表上的一个记录,包含上述八个域,其中乘员名单域为指向乘员名单链表的头指针,预约登记客户名单域为分别指向队头和队尾的指针。
### 回答1: 好的,我们需要做一些准备工作,首先我们要准备好cifar10数据集并导入相关的库。 ```python import numpy as np from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier # 导入数据 cifar10 = datasets.load_cifar10() X = cifar10.data y = cifar10.target # 将数据集分为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 创建k-NN分类器 knn = KNeighborsClassifier(n_neighbors=5) # 训练模型 knn.fit(X_train, y_train) # 评估模型 accuracy = knn.score(X_test, y_test) print('Accuracy:', accuracy) ``` 上面的代码展示了如何使用k-NN算法进行分类的基本流程。首先,我们导入了需要使用的库,包括`numpy`和`sklearn`中的`datasets`和`model_selection`模块。然后,我们使用`load_cifar10`函数导入了cifar10数据集,并将数据和标签存储在`X`和`y`变量中。接着,我们使用`train_test_split`函数将数据集分为训练集和测试集。然后,我们创建了一个k-NN分类器,并使用`fit`方法训练模型。最后,我们使用`score`方法来评估模型的准确率。 希望这个代码能帮到你! ### 回答2: CIFAR-10 数据集是一个常用的计算机视觉数据集,包含了来自10个不同类别的60000张32x32彩色图像。每个类别有6000张图像。其中50000张用于训练集,另外10000张用于测试集。 KNN(K-Nearest Neighbors)算法是一种简单而有效的分类算法。它通过计算该样本与训练集中的每个样本之间的距离,然后选取距离最近的k个训练样本中出现频率最高的类别作为预测结果。 要使用KNN算法完成对CIFAR-10数据集的分类,可以按照以下步骤进行: 1. 加载数据集: 首先,需要将CIFAR-10数据集导入到代码中。可以使用现有的库(如TensorFlow)来加载和处理数据集。 2. 数据预处理: 对于KNN算法,需要将图像数据转换为一维向量。可以将每个图像的RGB通道连接在一起,并将像素值归一化到0到1之间。 3. 计算距离: 在KNN算法中,常用的距离度量方式是欧氏距离。对于测试样本,需要计算它与训练集中每个样本的距离。 4. 选择最近的k个邻居: 根据计算的距离,选择与测试样本距离最近的k个训练样本。 5. 进行分类: 统计这k个最近邻居中每个类别的出现次数,并选择出现频率最高的类别作为预测结果。 6. 评估分类性能: 使用测试集对分类器进行评估,计算准确率或其他性能指标。 需要注意的是,KNN算法在处理大规模数据集时可能会比较缓慢,尤其是当特征维度较高时。因此,在实际应用中,可能需要采用一些优化措施,如使用KD树等数据结构来加速计算。 以上是使用KNN算法完成对CIFAR-10数据集的分类代码基本思路。根据具体的编程语言和库的选择,实际的代码实现可能会有所不同。 ### 回答3: K最近邻算法(K-Nearest Neighbors,KNN)是一种常用的监督学习算法,它根据样本间的距离来进行分类。下面是使用KNN算法对CIFAR-10数据集进行分类的代码。 首先,我们需要导入所需的库和模块。我们可以使用Python的机器学习库sklearn来实现KNN算法代码如下所示: ```python import numpy as np from sklearn.neighbors import KNeighborsClassifier from sklearn.metrics import accuracy_score from sklearn.datasets import load_breast_cancer from sklearn.model_selection import train_test_split # 载入CIFAR-10数据集 cifar = load_cifar() # 拆分数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(cifar.data, cifar.target, test_size=0.2, random_state=42) # 创建并训练KNN模型 k = 5 knn = KNeighborsClassifier(n_neighbors=k) knn.fit(X_train, y_train) # 在测试集上进行预测 y_pred = knn.predict(X_test) # 计算准确率 accuracy = accuracy_score(y_test, y_pred) print("准确率: ", accuracy) ``` 在代码中,我们首先导入了所需的库和模块,包括numpy、sklearn中的KNeighborsClassifier类和accuracy_score函数,以及load_cifar函数和train_test_split函数。 接下来,我们使用load_cifar函数加载CIFAR-10数据集。然后,我们使用train_test_split函数将数据集划分为训练集和测试集,其中测试集占总样本的20%。 然后,我们创建了一个KNN模型,其中k=5表示我们选择的邻居数。接着,我们使用fit函数对训练集进行训练。 在训练完成后,我们使用predict函数对测试集进行预测,得到预测结果y_pred。 最后,我们使用accuracy_score函数计算准确率,将预测的结果y_pred与实际标签y_test进行比较。准确率越高,说明模型的分类效果越好。 以上就是使用KNN算法对CIFAR-10数据集进行分类的代码汇总

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值