数据结构相关C语言代码

顺序存储结构

#include<stdio.h>
#include<stdlib.h>

typedef struct Arr
{
	int *pBase;//第一个下标的地址 (类似于数组名) 
	int lenth;//总长度(最多可存储数据) 
	int cnt;//实际数据长度 
}*PARR,ARR;

void init(PARR pArr,int len);//初始化数组 
void show_arr(PARR pArr);//输出数组 
bool is_empty(PARR pArr);//判断数组是否为空 
bool is_full(PARR pArr);// 判断数组是否已满 
bool append_arr(PARR pArr,int val);//在数组尾部增添数据val 
bool insert_arr(PARR pArr,int pos,int val);//在数组第pos个位置前插入数据val 
bool delete_arr(PARR pArr,int pos,int *pVal);//删除链表中第pos位置的数据,并把删除的数据存入*pVal中; 
void inversion_arr(PARR pArr);//将数组逆序 
void sort_arr(PARR pArr);//将数组内元素排序 

int main()
{
	ARR arr;
	int pos1,val1,pos2,dnum;
	init(&arr,6);
	printf("初始化后");
	show_arr(&arr);
	for(int i=1;i<=5;i++)
	append_arr(&arr,i);
	printf("\n增添后的");
	show_arr(&arr);
	printf("\n请输入插入的位置:");
	scanf("%d",&pos1);
	printf("请输入插入的数据:");
	scanf("%d",&val1);
	if(insert_arr(&arr,pos1,val1))
	{
	    printf("插入后的");
	    show_arr(&arr);
	}
	else
	{
		printf("插入失败");
	}
	printf("\n请输入删除的位置:");
	scanf("%d",&pos2);
	if(delete_arr(&arr,pos2,&dnum))
	{
		printf("删除的数据为:%d",dnum);
		printf("\n删除后的");
		show_arr(&arr);
	} 
	else
	{
		printf("删除失败");
	}
	inversion_arr(&arr);
	printf("\n逆序后的");
	show_arr(&arr);
	sort_arr(&arr);
	printf("\n排序后的");
	show_arr(&arr);
	return 0;
}
void init(PARR pArr,int len)//pArr只是定义的结构体指针,通过它可以调用结构体中的数据 
{
	pArr->pBase=(int *)malloc(sizeof(int)*len);//分配大小为len的空间为数组空间,此时pBase可当数组用 
	if(pArr->pBase==NULL)
	{
		printf("内存分配失败!!");
		exit(-1);
	}
	else
	{
		pArr->lenth=len; 
		pArr->cnt=0;
	}
	return ;
}
void show_arr(PARR pArr)
{
	if(is_empty(pArr))
	printf("顺序链表为空!!");
	else
	{
		printf("顺序链表为:");
		for(int i=0;i<pArr->cnt;i++)
		printf("%d ",pArr->pBase[i]);//输出pArr指向的结构体中的pBase数组 
	}
	return ;
}
bool is_empty(PARR pArr)
{
	if(pArr->cnt==0)//实际长度为0才为空 
	return true;
	else
	return false;
}
bool is_full(PARR pArr)
{
	if(pArr->cnt==pArr->lenth)//实际长度和最大长度相同是该数组已满 
	return true;
	else
	return false;
}
bool append_arr(PARR pArr,int val)
{
	if(is_full(pArr))//若数组已满则无法再在后面容纳数据 
	return false;
	pArr->pBase[pArr->cnt]=val;//注意:第cnt个数据的数组下标为cnt-1 
	pArr->cnt++;//实际长度++ 
	return true;
}
bool insert_arr(PARR pArr,int pos,int val)
{
	if(is_full(pArr))//若数组已满则无法再有插入内存 
	return false;
	if(pos<1||pos>pArr->cnt+1)//需要保证插入的位置存在,不能在小于实际长度cnt的位置插入,但是可以在最后一个数据cnt-1后的cnt插入,大于cnt+1的位置也不行,否则中间会存在空位 
	return false;
	for(int i=pArr->cnt-1;i>=pos-1;i--)//注意:第cnt个数据的数组下标为cnt-1,第pos个数据的数组下标为pos-1,若数组不为空则pos和cnt都不会为0
	pArr->pBase[i+1]=pArr->pBase[i];//通过循环实现第pos及以后的数据后移一位; 
	pArr->pBase[pos-1]=val;//第pos个位置插入了数据val 
	pArr->cnt++;//插入后长度++ 
	return true;
}
bool delete_arr(PARR pArr,int pos,int *pVal)
{
	if(is_empty(pArr))
	return false;
	if(pos<1||pos>pArr->cnt)//删除的位置不能不存在 
	return false;
	*pVal=pArr->pBase[pos-1]; //将删除的数据进行存储; 
	for(int i=pos;i<pArr->cnt;i++)
	pArr->pBase[i-1]=pArr->pBase[i];//让删除位置的后面的数据覆盖该删除数据,后面数据并整体前移 
	pArr->cnt--;//顺序链表长度-- 
	return true; 
}
void inversion_arr(PARR pArr)
{
	int i=0;//i为第一个元素下标 
	int j=pArr->cnt-1;//j为最后一个元素下标 
	int t;
	while(i<j)//头和尾依次逐渐交换,直到i,j相遇 
	{
		t=pArr->pBase[i];
		pArr->pBase[i]=pArr->pBase[j];
		pArr->pBase[j]=t;
		i++;
		j--; 
	}
	return ;
}
void sort_arr(PARR pArr) 
{
	int i,j,t;
	for(i=0;i<pArr->cnt-1;i++)
	{
		for(j=i+1;j<pArr->cnt;j++)
		{
			if(pArr->pBase[i]>pArr->pBase[j])
			{
				t=pArr->pBase[i];
				pArr->pBase[i]=pArr->pBase[j];
				pArr->pBase[j]=t;
			}
		}
	}
	return ;
}

链式存储结构:

#include<stdio.h> 
#include<stdlib.h>

typedef struct Node
{
	int data;
	struct Node *pNext;
} *PNODE;

PNODE creat_list(void);//创建链表 
void traverse(PNODE pHead);//输出链表 
bool is_empty(PNODE pHead);//判断该链表是否为空表 
int lenth_list(PNODE pHead);//求该链表的长度 
void sort_list(PNODE pHead);//给链表顺序排序
bool insert_list(PNODE pHead,int pos,int val);//从链表的第pos个位置插入数据val 
bool delete_list(PNODE pHead,int pos,int *pVal);//删除链表的第pos位置的数据并将数据存入指针pVal中;
 
int main()
{
	int pos,val,pos2,val2; 
	PNODE pHead=NULL;
	pHead=creat_list();//创建链表 
	if(is_empty(pHead)==false)//判断链表是否为空 
	{
		printf("\n该链表为空!!!");
	}
	else
	{
		traverse(pHead);//输出链表 
		printf("\n该链表为非空!!!"); 
	    printf("\n链表长度为%d",lenth_list(pHead));//计算长度 
	    sort_list(pHead);//排序 
	    printf("\n排序后");
	    traverse(pHead);
	    printf("\n请输入您要插入的位置:");//插入 
	    scanf("%d",&pos);
	    if(pos>lenth_list(pHead)+1)
		{
			printf("无法插入");
		}
		else
		{
			printf("请输入您要插入的数据为:");
	        scanf("%d",&val);
	        insert_list(pHead,pos,val);
	        printf("插入后");
	        traverse(pHead);
		}
	    printf("\n请输入您要删除的节点位置:");
	    scanf("%d",&pos2);
		if(delete_list(pHead,pos2,&val2))
		{
			printf("删除成功,您删除的节点数据为%d",val2);
			printf("\n删除后"); 
		    traverse(pHead);
		}
		else
		{
			printf("删除失败,该节点不存在");
		}
	}	
	return 0;
}
PNODE creat_list(void)
{
	int len;
	int val;
	int i;
	printf("请输入您创造的链表长度:");
	scanf("%d",&len);
	PNODE pHead=(PNODE)malloc(sizeof(Node));
	if(pHead==NULL)
	{
		printf("错误!!!");
		exit(-1);
	}
	PNODE pTail=pHead;
	pTail->pNext=NULL;
	for(i=0;i<len;i++)
	{
		printf("请输入第%d个数据:",i+1);
		scanf("%d",&val);
		PNODE pNew=(PNODE)malloc(sizeof(Node));
		if(pNew==NULL)
		{
			printf("错误!!!");
			exit(-1); 
		}
		pNew->data=val;
		pTail->pNext=pNew;
		pNew->pNext=NULL;
		pTail=pNew;
	}
	/*pTail->pNext=NULL;*/
	return pHead; 
}
void traverse(PNODE pHead)
{
	PNODE p=pHead->pNext;
	printf("该链表为:"); 
	while(p!=NULL)
	{
		printf("%d ",p->data);
		p=p->pNext;
	}
	return ;
}
bool is_empty(PNODE pHead)
{
	if(pHead->pNext==NULL)
	return false;
	else
	return true;
}
int lenth_list(PNODE pHead)
{
	PNODE p=pHead->pNext;
	int len=0;
	while(p!=NULL)
	{
		len++;
		p=p->pNext;
	}
	return len;
}
void sort_list(PNODE pHead)
{
	int i,j,t,len=lenth_list(pHead);
	PNODE q,p;
	for(i=0,q=pHead->pNext;i<len-1;i++,q=q->pNext)
	{
		for(j=i+1,p=q->pNext;j<len;j++,p=p->pNext)
		{
			if(q->data>p->data)
			{
				t=q->data;
				q->data=p->data;
				p->data=t;
			}
		}
	} 
}
bool insert_list(PNODE pHead,int pos,int val)
{
	int i=1;
	PNODE p=pHead;
	while(p!=NULL&&i<pos)//p是插入位置前的那一个整体数据 
	{
		p=p->pNext;
		i++;
	}
	if(p==NULL||i>pos)
	return false;
	PNODE pNew=(PNODE)malloc(sizeof(Node));
	if(pNew==NULL)
	{
		printf("错误!!!");
		exit(-1);
	}
	pNew->data=val;
	pNew->pNext=p->pNext;
	p->pNext=pNew;
	return true; 
}
bool delete_list(PNODE pHead,int pos,int *pVal)
{
	int i=1;
	PNODE p=pHead;
	while(p->pNext!=NULL&&i<pos)
	{
		p=p->pNext;
		i++;
	}
	if(p->pNext==NULL||i>pos)
	return false;
	PNODE q=p->pNext;
	*pVal=q->data;
	p->pNext=q->pNext;
	free(q);
	return true;
}

链式栈:

#include<stdio.h>
#include<stdlib.h>

typedef struct Node//节点结构 
{
	int data;
	struct Node *pNext;
}*PNODE;

typedef struct Stack//栈的头节点和尾节点 
{
	PNODE pTop;
	PNODE pBottom;
}STACK,*PSTACK;

void init(PSTACK pS);//初始化 
void push(PSTACK pS,int val);//压栈 
bool pop(PSTACK pS,int *pVal);//出栈 
void traverse(PSTACK pS);//输出栈 
bool is_empty(PSTACK pS);//判断栈是否为空 
void clear_stack(PSTACK pS);//清空栈内数据 
  
int main()
{
	int i,val;
	STACK S;
	init(&S);
	for(i=10;i>=0;i--)
	push(&S,i);
	traverse(&S);
	pop(&S,&val);
	printf("\n删除的顶部数据为:%d\n",val);
	traverse(&S);
	clear_stack(&S);
	printf("\n栈清空后"); 
	traverse(&S);
	return 0;
}
void init(PSTACK pS)
{
	pS->pTop=(PNODE)malloc(sizeof(Node));
	if(pS->pTop==NULL)
	{
		printf("分配失败!!!");
		exit(-1);
	}
	else
	{
		pS->pBottom=pS->pTop;
		pS->pTop->pNext=NULL;
	}
}
void push(PSTACK pS,int val)
{
	PNODE pNew=(PNODE)malloc(sizeof(Node));
	pNew->data=val;
	pNew->pNext=pS->pTop;
	pS->pTop=pNew; 
}
bool is_empty(PSTACK pS)
{
	if(pS->pTop==pS->pBottom)
	return true;
	else
	return false;
}
bool pop(PSTACK pS,int *pVal)
{
	if(is_empty(pS))//如果为真 
	return false;
	else
	{
		PNODE p=pS->pTop;
	    *pVal=p->data;
	    pS->pTop=p->pNext;
	    free(p);
	    p=NULL;
	    return true;
	}
}
void traverse(PSTACK pS)
{
	PNODE p=pS->pTop;
	printf("该栈为:");
	while(p!=pS->pBottom)
	{
		printf("%d ",p->data);
		p=p->pNext;
	}
}
void clear_stack(PSTACK pS) 
{
	if(is_empty(pS))
	return ;
	else
	{
		PNODE p=pS->pTop;
		PNODE q=NULL;
		while(p!=pS->pBottom)
		{
			q=p->pNext;
			free(p);
			p=q;
		}
	}
	pS->pTop=pS->pBottom;
}

循环队列

#include<stdio.h>
#include<stdlib.h>
# define size 6

typedef struct Queue
{
    int *pBase;
    int front;
    int rear;
}QUEUE,*PQUEUE;

void init(PQUEUE Q);
void traverse_queue(PQUEUE Q);
bool is_empty(PQUEUE Q);
bool is_full(PQUEUE Q);
bool EnQueue(PQUEUE Q,int val);
bool DeQueue(PQUEUE Q,int *pVal);

int main()
{
    QUEUE Q;
    int i,val1,val2;
    init(&Q);
    for(i=0;i<4;i++)
    EnQueue(&Q,i);
    traverse_queue(&Q);
    printf("\n请输入入队的数据为:");
    scanf("%d",&val1);
    EnQueue(&Q,val1);
    printf("插入后");
    traverse_queue(&Q);
    DeQueue(&Q,&val2);
    printf("\n出队的数据为:%d",val2);
    printf("\n删除后");
    traverse_queue(&Q);
    return 0;
}
void init(PQUEUE Q)
{
    Q->pBase=(int*)malloc(sizeof(int)*size);
    if(!Q->pBase)
    {
        printf("内存分配失败!!");
        exit(-1);
    }
    Q->front=0;
    Q->rear=0;
    return ;
}
void traverse_queue(PQUEUE Q)
{
    int p=Q->front;
    printf("该队列为:");
    while(p!=Q->rear)
    {
        printf("%d ",Q->pBase[p]);
        p=(p+1)%size;
    }
    return ;
}
bool is_empty(PQUEUE Q)
{
    if(Q->front==Q->rear)
    return true;
    else
    return false;
}
bool is_full(PQUEUE Q)
{
    if((Q->rear+1)%size==Q->front)
    return true;
    else
    return false;
}
bool EnQueue(PQUEUE Q,int val)//入队,队尾后移一位存入新数据
{
    if(is_full(Q))
    return false;
    else
    {
        Q->pBase[Q->rear]=val;
        Q->rear=(Q->rear+1)%size;
        return true;
    }
}
bool DeQueue(PQUEUE Q,int *pVal)//出队,队首后移一位,注意移动方向与队尾相同
{
    if(is_empty(Q))
    return false;
    else
    {
        *pVal=Q->pBase[Q->front];
        Q->front=(Q->front+1)%size;
        return true;
    }
}

二叉链表(二叉树)

//测试样例:ABC##DE#G##F### 
#include<stdio.h>
#include<stdlib.h>

typedef struct BtNode
{
	char data;
	struct BtNode *lchild;
	struct BtNode *rchild;
}BiTNode,*BiTree;

void creat_btree(BiTree *T);//创建树 
void Midtraverse_btree(BiTree T);//中序遍历输出树 
void copy(BiTree T,BiTree *NewT);//复制树 
int depth(BiTree T);//计算树的深度 
int NodeCount(BiTree T);//计算树的节点数 
int LeafCount(BiTree T);//计算叶子节点的个数 

int main()
{
	BiTree T=NULL;
	BiTree NewT=NULL;
	creat_btree(&T);
	printf("中序输出该树为:");
	Midtraverse_btree(T);
	copy(T,&NewT);
	printf("\n复制后中序输出该树为:"); 
	Midtraverse_btree(NewT);
	printf("\n该树深度为:%d",depth(T));
	printf("\n该树的节点数为:%d",NodeCount(T));
	printf("\n该树的叶子节点数为:%d",LeafCount(T));
	return 0;
}
void creat_btree(BiTree *T)
{
	char ch;
	scanf("%c",&ch);
	if(ch=='#')
	*T=NULL;
	else
	{
		*T=(BiTree)malloc(sizeof(BiTNode));
		(*T)->data=ch;
		creat_btree(&(*T)->lchild);
		creat_btree(&(*T)->rchild);
	}
	return ;
}
void Midtraverse_btree(BiTree T)
{
	if(T)
	{
		if(T->lchild)
		Midtraverse_btree(T->lchild);
		printf("%c ",T->data);
		if(T->rchild)
		Midtraverse_btree(T->rchild);
	}
	return ;
}
void copy(BiTree T,BiTree *NewT)//修改节点所指向的内存时一定要记住用二级指针 
{
	if(!T)
	*NewT=NULL;
	else
	{
		*NewT=(BiTree)malloc(sizeof(BiTNode));
		(*NewT)->data=T->data;
		copy(T->lchild,&(*NewT)->lchild);
		copy(T->rchild,&(*NewT)->rchild);
	}
	return ;
}
int depth(BiTree T)
{
	if(!T)
	return 0;
	else
	{
		int m=0,n=0;
		m=depth(T->lchild);
		n=depth(T->rchild);
		if(m>n)
		return m+1;
		else
		return n+1;
	}
}
int NodeCount(BiTree T)
{
	if(!T)
	return 0;
	else
	return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
int LeafCount(BiTree T)
{
	if(!T)
	return 0;
	if(!T->lchild&&!T->rchild)
	return 1;
	else
	return LeafCount(T->lchild)+LeafCount(T->rchild);	
}

邻接矩阵

#include<iostream>
#include<stdlib.h>
#define MVnum 100
#define MaxInt 0
using namespace std;

typedef struct Graph
{
	char vexs[MVnum];
	int arcs[MVnum][MVnum];
	int vexnum,arcnum;
} AMGraph;

void creatUDN(AMGraph &G);
void traverse_graph(AMGraph G);
int LocateVex(AMGraph G,char ch);

int main()
{
	AMGraph G;
	creatUDN(G);
	traverse_graph(G);
	return 0;
}
void creatUDN(AMGraph &G)
{
	int i,j,k;
	cout<<"请分别输入顶点数和边数:";
	cin>>G.vexnum>>G.arcnum;
	for(i=0;i<G.vexnum;i++)
	{
	    printf("\n请输入第%d个顶点:",i+1);
	    cin>>G.vexs[i];
	}
	for(i=0;i<G.vexnum;i++)
	{
		for(j=0;j<G.vexnum;j++)
		G.arcs[i][j]=MaxInt;
	}
	for(k=0;k<G.arcnum;k++)
	{
		char v1,v2;
		int m,n,w;
		printf("\n请输入第%d条边的两个顶点和权值:",k+1);
		cin>>v1>>v2>>w;
		m=LocateVex(G,v1);
		n=LocateVex(G,v2);
		G.arcs[m][n]=w;
		G.arcs[n][m]=G.arcs[m][n];
	}
	return ;
}
void traverse_graph(AMGraph G)
{
	int i,j;
	for(i=0;i<G.vexnum;i++)
	{
		for(j=0;j<G.vexnum;j++)
		printf("%d ",G.arcs[i][j]);
		cout<<endl;
	}
	return ;
}
int LocateVex(AMGraph G,char ch)
{
	int i;
	for(i=0;i<G.vexnum;i++)
	{
		if(G.vexs[i]==ch)
		return i;
	}
	return -1;
}

邻接表

#include<iostream>
#include<stdlib.h>
using namespace std;

#define MVnum 100

typedef struct Arcnode
{
	int adjvex;
	struct Arcnode *nextarc;
	int info;
}ArcNode;
typedef struct Vnode
{
	char data;
	ArcNode *firstarc;
}VNode,AdjList[MVnum];
typedef struct Graph
{
	AdjList vertices;
	int vexnum,arcnum;
}ALGraph;

void creatUDG(ALGraph &G);
void traverse(ALGraph G);
int LocateVex(ALGraph G,char ch);

int main()
{
	ALGraph G;
	creatUDG(G);
	traverse(G);
	return 0;
}
void creatUDG(ALGraph &G)
{
	int i,j,k;
	ArcNode *p1,*p2;
	char v1,v2;
	printf("请输入顶点数和边数:");
	cin>>G.vexnum>>G.arcnum;
	for(i=0;i<G.vexnum;i++)
	{
		printf("\n请输入第%d个顶点:",i+1);
		cin>>G.vertices[i].data;
		G.vertices[i].firstarc=NULL;
	}
	for(k=0;k<G.arcnum;k++)
	{
		printf("\n请输入第%d条边的两个顶点:",k+1);
		cin>>v1>>v2;
		i=LocateVex(G,v1);
		j=LocateVex(G,v2);
		p1=new ArcNode;
		p1->adjvex=j;
		p1->nextarc=G.vertices[i].firstarc;
		G.vertices[i].firstarc=p1;
		p2=new ArcNode;
		p2->adjvex=i;
		p2->nextarc=G.vertices[j].firstarc;
		G.vertices[j].firstarc=p2;
	}
	return ;
}
void traverse(ALGraph G)
{
	int i;
	printf("邻接表为:\n");
	for(i=0;i<G.vexnum;i++)
	{
		char q=G.vertices[i].data;
		ArcNode *p=G.vertices[i].firstarc;
		printf("%c ",q);
		while(p)
		{
			printf("%d ",p->adjvex);
			p=p->nextarc;
		}
		printf("\n");
	}
	return ;
}
int LocateVex(ALGraph G,char ch)
{
	int i;
	for(i=0;i<G.vexnum;i++)
	{
		if(G.vertices[i].data==ch)
		return i;
	}
	return -1;
}

这些只是部分主要基本函数,数据类型部分用的整型,可供参考(若有问题和错误请及时提出!!!

  • 7
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YXXYX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值