基础数据结构(c语言版)

数据结构

废话不多说,直接上代码

1.顺序表

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Maxsize 1000

typedef struct Sq{
	int *elem;
	int length;
}Sqlist;

int init(Sqlist* L){//初始化顺序表 
	L->elem = (int* )malloc(Maxsize* sizeof (int));
	if(L->elem==NULL) return 0;
	L->length = 0;
	return 1;
}

void Create_list(Sqlist* L){//创建顺序表 
	int n, x;
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		scanf("%d", &x);
		L->elem[i] = x;
		L->length++;
	}
}

int Getelem(Sqlist* L, int idx){//获取第idx位置的元素 
	int t = idx - 1;
	if(t<0||t>=Maxsize) return -1;
	for(int i = 0; i < Maxsize; i++){
		if(i==t) return L->elem[i];
	}
} 

int Insert(int idx, int x, Sqlist* L){//把x插入位置为idx的位置 
	if(L->length>=Maxsize) return 0;//顺序表满了 
	if(idx<1||idx>L->length) return 0;
	for(int i = L->length; i >= idx; i--){
		L->elem[i] = L->elem[i-1];
		
	} 
	L->elem[idx-1] = x, L->length++;
	return 1;
}

int Delete(int idx, Sqlist* L){//删除指定位置的元素 
	if(idx<1||idx>L->length) return 0;
	for(int i = idx - 1; i < L->length - 1; i++){
		L->elem[i] = L->elem[i+1];
	}
	L->length--;
	return 1;
}

void print(Sqlist* L){//打印顺序表 
	for(int i = 0; i < L->length; i++){
		printf("%d ", L->elem[i]);
	}
	printf("\n");
}
int main(){
	Sqlist* L;
	L = (Sqlist*) malloc(sizeof(Sqlist));
	init(L);
	Create_list(L);
	print(L);
	return 0;
} 

2.链表

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define len sizeof (Lnode)
using namespace std;

typedef struct Lnode{
	int elem;
	struct Lnode* next;
}Lnode;


void Create1_list(Lnode* head){//头插法,并且头指针不存数据 
	Lnode* p = NULL;
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		p = (Lnode*) malloc(sizeof (len));
		p->next = NULL;
		scanf("%d", &p->elem);
		p->next = head->next; 
		head->next = p;
	}
}

void Create2_list(Lnode* head){//尾插法,并且头指针不存数据 
	Lnode* p2 = NULL;
	int n;
	scanf("%d", &n);
	for(int i = 0; i < n; i++){
		Lnode* p1 = (Lnode*)malloc(sizeof (len));
		p1->next = NULL;
		scanf("%d", &p1->elem);
		if(!head->next) {
			head->next = p1;
			p2 = p1;
		}
		else {
			p2->next = p1;
			p2 = p1;
		}
	}
}

int Insert(int idx, int x, Lnode* head){//如果插入位置大于链表长度,则插到表尾 
	if(idx<1) return 0;
	int j = 0;
	Lnode* p = head;
	while(p->next&&j<idx-1){
		p = p->next;
		j++;
	}
	Lnode* q = (Lnode*)malloc(sizeof (len));
	q->elem = x, q->next = NULL;
	q->next = p->next;
	p->next = q;
	return 1;
}

void Delete(int idx, Lnode* head){//删除指定位置的节点 
	int j = 1;
	Lnode* p = head;
	while(p&&j<idx){
		p = p->next;
		j++;
	} 
	if(p&&p->next){
		p->next = p->next->next;
	}
}
void print(Lnode* head){//打印 
	for(Lnode* t = head->next; t; t = t->next){
		printf("%d ", t->elem);
	}
}
int main(){
	Lnode* head = (Lnode*) malloc(sizeof (len));
	head->next = NULL;
	Create2_list(head);
	Delete(3, head);
	print(head);
	return 0;
}

3.顺序栈

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Maxsize 100
#define null 0X3f3f3f3f

typedef struct Sqstack{
	int *base;
	int *top;
}Stack;

void init(Stack *stk){
	stk->base = (int*)malloc(Maxsize*sizeof(int));
	stk->top = stk->base;
}

void Push(int x, Stack *stk){
	*(stk->top++) = x;
}

int Top(Stack *stk){//如果为空,返回null(0X3f3f3f3f) 
	if(stk->base==stk->base) return null;
	return *(stk->base-1);	
}
void Pop(Stack *stk){
	if(stk->top==stk->base) return ;
	stk->top--;
}

void print(Stack *stk){//遍历栈中的元素
	while(stk->top!=stk->base){
		printf("%d ", *(stk->top-1));
		stk->top--;
	}
} 
int main(){
	Stack *stk = (Stack*)malloc(sizeof(Stack));
	init(stk);
	Push(1, stk);
	Push(2, stk);
	Push(3, stk);
	Pop(stk);
	print(stk);
	return 0;
}

4.队列

顺序队列的假溢出
所以这里我们采用一个循环的思想
1.顺序队列

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Maxsize 1000
#define null 0X3f3f3f3f
typedef struct Sqqueue{
	int *base;
	int front, rear;
}Queue;
void init(Queue *q){
	q->base = (int*)malloc(Maxsize*sizeof(int));//由于判断队列是否满了,这里的Maxsize实际上只用了Maxsize-1个位置 
	q->front = q->rear = 0;
} 

void Push_back(int x, Queue *q){//把x插到队尾 
	if((q->rear+1)%Maxsize==q->front) {
		printf("队列满了");
		return ; 
	} 
	q->base[q->rear] = x;
	q->rear = (q->rear+1)%Maxsize; 
} 

int Get_front(Queue* q){
	if(q->front==q->rear) return null;
	return q->base[q->front];	
}
void Pop_front(Queue* q){
	if(q->front==q->rear){
		printf("当前队列无元素");
		return ;
	}
	q->front = (q->front+1)%Maxsize;
}

int main(){
	Queue *q = (Queue*)malloc(sizeof(Queue));
	init(q);
	Push_back(1, q);
	Push_back(2, q);
	printf("%d ", Get_front(q));
	Pop_front(q);
	printf("%d ", Get_front(q));
	return 0;
}

5.树

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define Elemtype char

typedef struct Btree{
	Elemtype val;
	struct Btree *left, *right;
}Btree;

typedef struct Node{
	Btree* val;
	struct Node* next;
}Node;//typedefine了个寂寞hhh 

typedef struct Sqqueue{//这里采用链队列 
	Node* front;
	Node* rear;
}Queue;

void Push_back(Btree* e, Queue* q){//把元素加到队尾 
	q->rear->val = e;
	Node* p = (Node*)malloc(sizeof(Node));
	p->next = NULL;
	q->rear->next = p;
	q->rear = p;
} 

Btree* Get_front(Queue* q){//获取队头元素 
	if(q->front==q->rear) return NULL;
	return q->front->val; 
}

void Pop_front(Queue* q){//把队头元素移除队列 
	Node* p = q->front;
	q->front = q->front->next;
}

int is_Empty(Queue* q){//判断队列是否为空 
	if(q->front==q->rear) return 0;
	return 1;
}

void Create_tree(Btree* *T){//创建二叉树 
	char ch;
	scanf("%c", &ch);
	if(ch=='*') *T = NULL;
	else {
		*T = (Btree*)malloc(sizeof(Btree));
		(*T)->val = ch;
		Create_tree(&(*T)->left);
		Create_tree(&(*T)->right);
	}
}

void preorder(Btree* T){//先序遍历 
	if(T!=NULL){
		printf("%c ", T->val);
		preorder(T->left);
		preorder(T->right);
	}
}

void inorder(Btree* T){//中序遍历 
	if(T){
		preorder(T->left);
		printf("%c ", T->val);
		preorder(T->right);
	}
}


void posorder(Btree* T){//后序遍历 
	if(T){
		preorder(T->left);
		preorder(T->right);
		printf("%c ", T->val);
	}
}

void traverse(Btree* T){
	Queue* q = (Queue*)malloc(sizeof(Queue));
	q->front = (Node*)malloc(sizeof(Node));
	q->front->next = NULL;
	q->rear = q->front;
	if(T) Push_back(T, q);
	while(is_Empty(q)){
		Btree* t = Get_front(q);
		Pop_front(q);
		printf("%c ", t->val);
		if(t->left){
			Push_back(t->left, q);
		} 
		if(t->right){
			Push_back(t->right, q);
		}
	}
} 


int Get_leaf(Btree* T){
	if(!T) return 0;
	else {
		if(!T->left&&!T->right) return 1;
		else return Get_leaf(T->left)+Get_leaf(T->right);
 	}
} 

int Get_depth(Btree* T){
	if(!T) return 0;
	else {
		//return max(Get_depth(T->left), Get_depth(T->right)) + 1;
		int a = Get_depth(T->left), b = Get_depth(T->right);
		if(a>b) return a+1;
		else return b+1;
	}
}
int main(){
	Btree *T = NULL;
	Create_tree(&T);
	traverse(T);
	posorder(T);
	printf("当前二叉树的叶子数为:%d\n", Get_leaf(T));
	printf("当前二叉树的深度为:%d\n", Get_depth(T));
	return 0;
}

这里要传入的是指针的指针,一开始我传入的仅仅是指针,后来发现错了。至于为什么是错的,我认为是在创建的过程中会对这个T指针不断的移动(递归嘛),以至于修改了T指针所指向的空间。所以这里我们需要传入指针的指针。
关于&为什么能表示指针的指针,我举一个例子:

	int x = 10;
	int *p = &x;
	printf("%d %d", p, *p);

打印结果是 6487572 10
第一个代表p地址值,第二个*p代表解引用。这也就很好的反映了指针的本质(就是指向一块空间),所以这里可以用&来完成一个降维操作。
第一次写错误难免有,欢迎指正!

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值