c语言的数据结构的链表的一些基本操作(一)

链表的一些基本操作
还有一些注释了(因为我也不知道写的对不对)
鬼知道我费了多大劲,浪费多大时间在一些小错误上
心好累
至少能编译能过了

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

typedef int elemtype;

typedef struct lnode{
elemtype data;
struct lnode *next;
}lnode,*linklist;//lnode类型的指针,顺序链表

int initlist(linklist &L){//头节点的数据域可以不存信息,也可以存附加信息(不是数据),意思是头节点的位置为0,且不能插入到0位置
L=(linklist)malloc(sizeof(lnode));//L为头指针,指向表中第一个节点
if(L==0){//你个脑瘫,俩=都能少写一个 ,害我困扰几个月
printf(“分配空间失败\n”);
exit(-1);
}
L->next = NULL; //初始化使第一个节点指空,即第一个节点的指针域为空,意思是现在为空表
printf(“初始化成功\n”);
return 0;
}

int destorylist(linklist &L){
linklist p,q;
p = L->next;
while(p!=NULL){
q= p->next;
free§;
p =q;
}
L->next = NULL;
printf(“链表已销毁\n”);
return 0;
}

int listlenth(linklist &L){
linklist p;
int n = 0;//n记录长度,并返回n
p = L->next;//下个指针域不为空p时,计数加1,指针指向下一个
while(p!=NULL){
n++;
p = p->next;
}
return n;
}

int get_elem(linklist L,int i,elemtype &e){//已知位序求元素
int j = 1;//计数器
linklist p;
p = L->next;
while(p!=NULL&&j<i){//让p指向i那个位置
p = p->next;
++j;
}
if(p==NULL||j>i)
{
printf(“第i个元素不存在\n”);
return -1;
}
e = p->data;
return e;
}//具体思路就是给个指针一直往后走,位置到了给值,没到不存在,while循环控制 p = p->next;++j;

int locateelem(linklist L,int cur_e){ //已知元素求位序
int i = 0;
linklist p;
p = L->next;
while(p!=NULL){
if(p->data ==cur_e&&p!=NULL){
i++;
}
p=p->next;
}
return i;
}

void priorelem(linklist L,elemtype cur_e){//前驱
// linklist p,q;
// elemtype pre_e;
// p = L->next;
// q=p->next;//p前q后
// while(p!=NULL){
// if§{
// if(cur_e==q->data){
// printf(“222\n”);
// pre_e = p->data;
// printf(“前驱为%d\n”,pre_e);
// return pre_e;
// }
// }
// else{
// printf(“p值为空\n”);
// }
// p=q;
// q = p->next;
// }
// printf(“没有找到当前元素值\n”);
linklist p = L->next,q = p->next;
while(q)
{
if(cur_e == q -> data)
{
if§
printf(“所求前驱为:%d\n”,p->data);
else
printf(“该节点无前驱\n”);
return;
}
else
{
p = q;
}
q = p->next;
}

}

int nextelem(linklist L,int cur_e, elemtype next_e){//后继
linklist p,q;
p=L;//p前q后
while(p!=NULL){
q=p->next;//两个指针都后移!!!
if(p!=NULL&&p->data==cur_e)
{
next_e = q->data;
return next_e;
}
p = p->next;
p = q;
}
printf(“没有找到当前元素值\n”);
}

int listinsert(linklist L,int i,elemtype e){//链表是从1开始的 ,i是所要插入的位置
linklist p,s;
int j=0;
p=L;//这样p成头节点了,设头节点吧 p=L->next;这样写是错的,L就是个头节点,这样写L就是空的 ,也就是说表长为1的地方为头节点
while(p&&j<(i-1)){//要找i-1的那个位置,将p指向那个位置
p=p->next;//假如你第一个为空,却插入了第二个,你第一次找的时候p为空,循环就不会进行
j++;
}
if(!p||j>i-1){//i小于1或大于表长加1
printf(“i小于1或大于表长加1\n”);
return -1;
}
s =(linklist)malloc(sizeof(lnode));//要插入就新生成节点,分配内存
s->data = e;//新生成的节点的数据域
s->next=p->next;//下面这两步,意思是有原先在前面的p节点,和新生成的s节点
//p->next指下一个节点,把下一个节点放到s的指针域,把第三个节点放到第二个的指针域里里
p->next=s;//要把s插入到p的后面 ,p的下一个指s
printf(“插入成功\n”);
return 0;
}

int listdelete(linklist L,int i,elemtype e){//e只是为了返回
linklist p,q;
p=L;
int j=0;
while(p->next&&j<i-1){//找i-1个节点 ,当p的next不为空时往后找
p=p->next;
j++;
}//令p指向i-1个节点
if(!(p->next)&&j>i-1){//如果开始p的next就为空,上面的循环直接就结束了,所以这里再看一遍p的next是否为空
printf(“删除位置不合理\n”);
return -1;
}
q=p->next;//q指向第i个节点,p在前,q在后
p->next=q->next;//这两步等价于p->next = p->next->next,就不要中间变量q了
e = q->data;
free(q);//先改值再释放空间,先释放空间会怎么着呢,改值失败,后面的没法移动
printf(“删除成功\n”);
return e;
}//这不就是很正常的操作吗,哪里不对了,把q的下一个放到p的下一个里
//删最后一个也没问题,只是一开始q为空而已

int shuchu(linklist L){
linklist p;
p=L->next;
while(p!=NULL){
printf("%d\n",p->data);
p=p->next;
}
return 0;
}
//void shuru(linklist L){//哪个憨批写的,这怎么会输入进去
// L=(linklist)malloc(sizeof(lnode));
// if(L0){
// printf(“初始化失败\n”);
// exit(-1);
// }
// L->next = NULL;
// linklist p;
// p=L->next;
// while(p!=NULL){
// printf(“请输入链表元素:\n”);
// scanf("%d",p->data);
// p=p->next;
// }
//
//}
//int fanzhuan(linklist L){
// if(NULL == head || NULL == new_node)
// return -1;
// new_node->pNext = head->pNext;
// head->pNext = new_node;
// return 0;
//}
//int guibing(linklist L,linklist G){
// linklist p,q;
// p=L->next;
// q=G->next;
// linklist S;
// S=(linklist)malloc(sizeof(L));
// if(L!=0){
// exit(-1);
// }
// for(int i=0;i<=L.length;i++){//第一个是L表的所有元素的循环
// for(int j =0;j<=G.length;j++){//第二个是L表的一个元素与G表中所有的比较
// if(p->data
q->data){
//
//
// }
// else{
//
// }
// }
// }
//}
//int addnodehead(lnode *head, lnode *new_node)
//{
// if( head== NULL || new_node ==NULL ){
// return -1;
// }
// node->next = head->next;
// head->next = next;
// return 0;
//}

//int revert(lnode *head)
//{
// if(NULL == head){
// return 0;
// }
// lnode *p = head->next;
// head->next= NULL;
// lnode *temp = NULL;
// while§
// {
// temp = p->next;
// addnodehead(head, p);
// p = temp;
// }
// return 0;
//}

int main(){
int option;
int i;
elemtype cur_e,pre_e,next_e;
int length;
elemtype e;
linklist L,G;
while(1){
printf(“1----初始化或重置一个链表\n”);//
printf(“2----销毁链表\n”);
printf(“3----链表长度\n”);//
printf(“4----返回这个位置的元素值\n”);
printf(“5----链表已存在元素的位序\n”);
printf(“6----请输入元素,求直接前驱\n”);//
printf(“7----请输入元素,求直接后继\n”);//
printf(“8----在第i个位置插入元素\n”);//
printf(“9----删除第i个元素\n”);//
printf(“10----输出所输入的链表元素\n”);//
printf(“12----退出\n”);
printf(“请选择操作:\n”);
scanf("%d",&option);
switch(option){
case 1:
initlist(L);
continue;
case 2:
destorylist(L);
continue;
case 3:
length = listlenth(L);
printf(“链表长度为:%d\n”,length);
continue;
case 4:
printf(“请输入位置\n”);
scanf("%d",&i);
e=get_elem(L,i,e);
printf(“这个位置的值为:%d\n”,e);
continue;
case 5:
locateelem(L,e);
continue;
case 6:
printf(“请输入当前元素cur_e:\n”);
scanf("%d",&cur_e);
priorelem(L,cur_e);
continue;
case 7:
printf(“请输入当前元素cur_e:\n”);
scanf("%d",&cur_e);
next_e=nextelem(L,cur_e,next_e);
printf(“后继为:%d\n”,next_e);
continue;
case 8:
printf(“请输入位置i:\n”);
scanf("%d",&i);
printf(“请输入要插入的元素e:\n”);
scanf("%d",&e);
listinsert(L,i,e);
continue;
case 9:
printf(“请输入位置i:\n”);
scanf("%d",&i);
printf(“请输入要删除的元素e:\n”);
scanf("%d",&e);
e=listdelete(L,i,e);
printf(“删除的元素为:%d\n”,e);
continue;
case 10:
printf(“链表的值为:\n”);
shuchu(L);
continue;
case 11:
exit(-1);
}
//归并 ,不使用原空间
// linklist p,q,r;
// p=L->next;
// q=G->next;
// linklist S;
// S=(linklist)malloc(sizeof(listlength(L)+listlength(G)));
// if(S!=0){
// exit(-1);
// }
// r=S->next;
// for(int i=0;i<=listlength(L);i++){//第一个是L表的所有元素的循环
// for(int j =0;j<=listlength(G);j++){//第二个是L表的一个元素与G表中所有的比较
// if(p->dataq->data){
// r->data=p->data;
// r=r->next;
// }
// else if(p->data>q->data){
// r->data=q->data;
// r=r->next;
// r->data=p->data;
// r=r->next;
// }
// else{
// r->data=p->data;
// r=r->next;
// r->data=q->data;
// r=r->next;
// }
// p=p
// }
// }
//使用旧空间
// linklist p,q,r;
// p=L->next;
// q=G->next;
// L=(linklist)realloc(L,sizeof(linklist)*(listlength(L)+listlength(G)));
// for(int i=0;i<=listlength(L);i++){//第一个是L表的所有元素的循环
// for(int j =0;j<=listlength(G);j++){//第二个是L表的一个元素与G表中所有的比较
// if(p->data
q->data){
// p=p->next;
// }
// else if(p->data>q->data){
// p->data=q->data;
// p=p->next;
// p->data=p->data;
// p=p->next;
// }
// else{
// p->data=p->data;
// p=p->next;
// p->data=q->data;
// p=p->next;
// }
// }
// }
}
return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值