栈
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;
}