一些数据结构的简单实现,持续更新~

文章目录

struct stack_node{
	char name[30];
	struct stack_node * prior;
};

struct stack_node * tosp; //栈顶指针

void push(char * name);
void pop(char * name);

void read_push();
void pop_show();

#define DEBUG 1

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
	tosp = NULL; //初始化栈指针
	
	read_push();
	pop_show();

	return 0;
}

void read_push()
{
	char name[30];
	while (1)
	{
		printf("输入一个姓名,输入q结束输入:\n");
		gets(name);
		if (0 == strcmp(name, "q"))
			break;
		push(name);
	}
}

void pop_show()
{
	char name[30];
	while (tosp)
	{
		pop(name);
		printf("%s\n", name);
	}
}

void push(char * name)
{
	if (DEBUG)
		printf("current tosp addr is %p .\n", tosp);

	struct stack_node * p_temp = (stack_node *)malloc(sizeof(stack_node));
	strcpy(p_temp->name, name);
	p_temp->prior = tosp;
	tosp = p_temp;
}

void pop(char * name)
{
	if (DEBUG)
		printf("current tosp addr is %p .\n", tosp);

	struct stack_node * p_temp = tosp;
	tosp = tosp->prior;
	strcpy(name, p_temp->name);
	free(p_temp);
}


队列
#include <stdlib.h>
#include <stdio.h>
#define node_que struct node_queue
struct node_queue{
	int data;
	node_que * next;
};

node_que * p_in = NULL; //入队指针(队尾指针)
node_que * p_out = NULL;//出队指针(队首指针)

void enque(int data);//入队
void serve(int * data, int * sucess);//出队

void test_in_queue();
void test_out_queue();
void print_queue();

int main()
{

	while (1)
	{
		printf("---------------------------------------------------\n");
		printf("\
请选择功能:\n\
1)测试入队\n\
2)测试出队\n\
3)打印队列\n\
q)退出\n:");
		char buf_fun[5];
		gets(buf_fun);
		switch (buf_fun[0])
		{
		case '1': test_in_queue(); break;
		case '2': test_out_queue(); break;
		case '3': print_queue(); break;
		case 'q': goto end;//此处应该释放内存,为了简明,省略之。
		}
	}
end:;
	return 0;
}

void enque(int data) // 入队,入队时需要判断入队前队列空的情况
{
	node_que * new_node = (node_que*)malloc(sizeof(node_que));//创建新结点
	new_node->data = data; //给新结点填充数据
	new_node->next = NULL; //新结点next指向null
	if (NULL == p_out)
		p_out = new_node; //如果队列为空,把p_out指向新结点,即把新结点设为队首
	else
		p_in->next = new_node; //如果队列不为空,把队尾结点的next指向新结点,即把新结点加在队尾
	p_in = new_node;//把p_in 指向新结点,即把新结点设为队尾
}

void serve(int * data, int * sucess) //出队,出队需判断出队后队列是否空
{
	if (NULL == p_out)
	{
		printf("队列为空,不能出队\n");
		*sucess = 0;//标记失败
		return;
	}
	*data = p_out->data; //取出队首结点的数据。
	node_que * new_p_out = p_out->next; //取出队首结点的next作为新的 p_out
	free(p_out);//此时队首结点中有用的数据已经提取出,可以释放其空间
	if (NULL == new_p_out)
		p_in = NULL; //如果出队后队列为空,把p_in也置为NULL;
	p_out = new_p_out; //更新p_out的值
	*sucess = 1;//标记成功
}

void test_in_queue()
{
	printf("请输入一个数,作为结点的值,这个结点将被加到队尾\n");
	int data;
	scanf("%d", &data);
	fflush(stdin);
	enque(data);
}

void test_out_queue()
{
	int data;
	int f;
	serve(&data,&f);
	if (f)
		printf("队首结点出队了,这个出对了的结点数据域的值是%d\n", data);
	else
		printf("队列空,出队失败。\n");
}

void print_queue()
{
	node_que * p_temp = p_out;
	printf("队列内容如下(从队首到队尾):\n");
	while (p_temp)
	{
		printf("%d->", p_temp->data);
		p_temp = p_temp->next;
	}
	printf("NULL\n");
}

在这里插入图片描述
//出队指针,又叫队首指针,指向队首结点
//入队指针,又叫队尾指针,指向队尾结点

入队时,只需要知道队尾结点的位置。
出队时,即需要知道队首结点,有需要知道队首结点下一个结点x的位置。因为队首结点出队后,要用结点x的地址作为队首指针的值。
所以,队列的存储方式被安排为,next从队首方向指向队尾方向。
如果next从队尾方向指向队首方向的话,出队时,更新队首指针将会特别困难。



链表
#include <stdio.h>
#include <stdlib.h>
struct Node{
	int data;
	struct Node * next;
};
void errorIndexTooLong(int inWhere)
{
	printf("位置非法,不能为%d\n", inWhere); 
	exit(1);
}
struct Node * NewList()//没有头结点的链表
{
	return NULL;
}
void addNode(int data, struct Node ** listHead)//功能,在链表尾部增加结点。
{												//如果是空结点的话,需要修改头指针,所以传入参数为指向头指针的指针。
	struct Node * newp = (struct Node *)malloc(sizeof(struct Node));
	newp->data = data;
	newp->next = NULL;
	if (*listHead == NULL)//对于没有空头结点的链表,增加结点时要先判断链表空否
	{
		*listHead = newp; return;
	}
	struct Node * p = *listHead;//不能直接用(*listHead)去遍历到最后一个结点,如果那样做的话,头结点会被覆盖,导致找不到链表。
	while (p->next)
		p = p->next;
	p->next = newp;
}
void InsertNode(int data, int inWhere, struct Node ** listHead)//再链表中插入一个元素,inWhere为插入位置,从0开始计数。插入到inWhere后
{
	struct Node * newp = (struct Node *)malloc(sizeof(struct Node));
	newp->data = data;
	newp->next = NULL;
	if (*listHead == NULL)//如果是空链表,直接插入尾部。
	{
		if (inWhere)//如果插入位置不是0,报错。
			errorIndexTooLong(inWhere);
		*listHead == newp; return;//如果位置合法,插入,返回。
	}
	struct Node * p = *listHead;//链表非空的处理
	for (int i = 0; i < inWhere; i++)
	{
		p = p->next;
		if (!p)//如果插入位置超过链表长度,报错。
			errorIndexTooLong(inWhere);
	}
	newp->next = p->next;
	p->next = newp;
}
void printNode(struct Node * p)
{
	printf("head");
	if (!p)
	{
		printf("->NULL\n");
		return;
	}
	while (p)
	{
		printf("->");
		printf("%d", p->data);
		p = p->next;

	}
	printf("\n");
}
int main()
{
	struct Node * list = NewList();
	printNode(list);
	addNode(1, &list);
	printNode(list);
	addNode(2, &list);
	InsertNode(3, 0, &list);
	InsertNode(8, 2, &list);
	printNode(list);
	return 0;
}


end
发布了111 篇原创文章 · 获赞 13 · 访问量 3122

猜你喜欢

转载自blog.csdn.net/wx_assa/article/details/103544996
今日推荐