链表、栈、队列的实现
#include<stdio.h>
#include<malloc.h>
typedef struct KK{
int num;
struct KK *xia;
} LB;
LB *charu(LB *aa, int num)//有序插入链表
{
LB *bb = 0;
LB temp;
if (aa == 0){ //如果传进来是空指针的话,那就进行内存地址申请工作
bb = (LB *)malloc(sizeof(struct KK));
bb->num = num;
bb->xia = 0;
return bb;
}else{
if (aa->num<num){//比较传进来的数,如果数值比当前链表里面的数值大,那就继续往下比较
aa->xia=charu(aa->xia, num);//递归调用,继续往下寻找
return aa; //要记得返回原来的地址
}else{//找到插入的位置了
bb =(LB *)malloc(sizeof(struct KK));//申请内存地址
bb->num = num;//赋值
bb->xia = aa;//将新的指向当前链表
return bb;//返回新的指针
}
}
}
LB * sanchu(LB *aa, int num)
{
LB *temp = 0;//保留头指针
LB *lasttemp = 0;
char flag = 0;//标志是否删头指针
if (aa != 0) temp = aa;//保留头指针
while (aa != NULL){//查询对应的数据
if (aa->num == num){//找到删除的数据
if (flag == 0){//删除头指针
temp = aa->xia;//保留头指针指向的下一个指针
free(aa);//收回头指针的内存
break;
}else{
lasttemp->xia = aa->xia;//当前的上一个指针直接链接到当前的下一个指针
free(aa);//将当前的指针内存收回
break;
}
}
lasttemp = aa;//保存上一个指针
aa=aa->xia;//继续向下查找
flag = 1;//置1了说明不是头指针了
}
return temp;//返回头部指针
}
void main01(void)
{
LB *a =0;
LB *temp = 0;
a =charu(a, 12);
a =charu(a, 16);
a =charu(a, 5);
a =charu(a, 3);
temp = a;
while (temp != NULL){
printf("%d\n", temp->num);
temp = temp->xia;
}
printf("1---------------------\n");
a = sanchu(a, 16);
a = sanchu(a, 3);
temp = a;
while (temp != NULL){
printf("%d\n", temp->num);
temp = temp->xia;
}
a = sanchu(a, 12);
a = sanchu(a, 5);
printf("2---------------------\n");
while (temp != NULL){
printf("%d\n", temp->num);
temp = temp->xia;
}
}
//-----------------------------------------------------------------------------------------------链表
//用指针实现一个栈
typedef struct zz{
int num;
struct zz *xia;
} zz;
zz *push(zz *aa, int num)
{
zz *bb = malloc(sizeof(struct zz)); //直接申请一个地址
bb->num=num;
bb->xia=aa;
return bb;
//由于栈都是先进后出的,每生成一个指针都必须当成是头指针
}
zz *pop(zz *aa, int *num)
{
zz *bb = 0;
if(aa->xia!=0) bb=aa->xia;
*num=aa->num; //取出数据
free(aa);
return bb;
//由于栈都是先进后出的,每生成一个指针都必须当成是头指针
}
void main02(void)
{
zz *a=0;
int num2=0;
a=push(a,12);
a=push(a,100);
a=push(a,257);
a=pop(a,&num2);
a=push(a,666);
a=push(a,888);
while(a!=0){
a=pop(a,&num2);
printf("%d\n",num2);
}
}
//用指针实现一个队列
typedef struct dl{
int num;
struct dl *xia;
} dl;
//由于栈都是先进先出的,每生成一个指针都要插入到末尾
dl *push_dl(dl *aa, int num)
{
dl *temp=0;
dl *bb = malloc(sizeof(struct dl)); //直接申请一个地址
if(aa==0){
bb->num=num;
bb->xia=0;
return bb;
}else{
temp=aa;//保留头指针
while(temp->xia!=0){ //找出末尾指针
temp=temp->xia;
}
bb->num=num;//将新加的插到末尾上面
bb->xia=0;
temp->xia=bb;
return aa;
}
}
dl *pop_dl(dl *aa, int *num)
{
dl *bb = 0;
if(aa->xia!=0) bb=aa->xia;
*num=aa->num; //取出数据
free(aa);
return bb;
}
void main(void)
{
dl *a=0;
int num2=0;
a=push_dl(a,12);
a=push_dl(a,100);
a=push_dl(a,257);
a=push_dl(a,666);
a=push_dl(a,888);
while(a!=0){
a=pop(a,&num2);
printf("%d\n",num2);
}
}
实现过程中碰到的问题:
刚开始实现链表的时候,我就进行指针的传参,然后出现了问题,就比如:
void charu(LB *p,int num)
{
p=malloc(sizeof(LB));
//其他的操作..........
}
void main(void)
{
LB *a=0;
charu(a,20);
}
我以为a会顺利得到函数charu里面申请的地址,我以为a传参给函数charu中的p之后,a和p就是一样的了,其实不是这样的p是一个独立的备份变量,p的地址只不过是指向了啊,但是后面执行 p=malloc(sizeof(LB))之后,p就指向了一个新的地址,与a没有半毛钱关系了,要么就像上面我用return的方法赋值给a,要么就用双重指针
void charu(LB **p,int num)
{
* p=malloc(sizeof(LB));
//其他的操作..........
}
void main(void)
{
LB *a=0;
charu(&a,20);
}