线性表的单链表

#include<stdio.h>
#include<malloc.h>

typedef int Elemt;

typedef struct LNode{
Elemt data;
struct LNode *next;

}LNode,*Linklist;


#define ERROR 0
#define OK 1

 

 //创建一个空的结点,并将其放到链表的中(依次,这里的入口结点为要插入位置的前一个结点切记)
Elemt create_jiedian_biao(Linklist L){
int i;
 Linklist p,q,m;
 q=L;
 m=L;
 
 p=(Linklist)malloc(sizeof(LNode));
 if(!p) return ERROR;
 p->next=q->next ;
 q->next = p;
 return OK;

}
//s顺序建立一个指定大小的单链表
int   creat_biao_shunxu(Linklist L,int n){
 int i;
 Linklist p,q,m;

 L->data=n;
 L->next=NULL;
 q=L;
 m=L;
 
 for(i=1;i<=n;i++){
 p=(Linklist)malloc(sizeof(LNode));
  scanf("%d",&p->data);
  p->next=q->next ;
  q->next = p;
  q=p;
 }

printf("遍历............................\n");
 for(i=1;i<=n;i++){
 m=m->next;
 printf("%d\n",m->data);
  }

 printf("遍历完..........................\n"); 
 //printf("%d\n",L->data);
 //printf("..........................\n"); 

 
 return OK;
}

 

//逆序建立一个指定大小的链表
int creat_biao(Linklist L,int n){
 int i;
 Linklist p;
 L->data=n;
 L->next=NULL;

 for(i=n;i>0;i--){
  p=(Linklist)malloc(sizeof(LNode));
  scanf("%d",&p->data);//这里p只是指结点内部,因而在p->data时需要用&
  p->next=L->next;L->next=p;
 }
 p=L->next;
 for(i=1;i<=n;i++){
  
 printf("%d\n",p->data);
 p=p->next;
 }
 printf("..........................\n");
 return OK;
}


Elemt back_e_i_biao(Linklist L,int i,int *e){
 int n=1;
 Linklist p,m;
 p=L;
 m=L;
 printf("to here \n");
 if( i<1 || i>L->data ){printf("error\n"); return ERROR;}
 //if(!p){ printf("error\n"); return ERROR;}
 
 while(n<=i){
 p=p->next;n++;

 }
 
 *e=p->data;
 printf("e is :%d\n",*e);

 return OK;
}


void destory_biao(Linklist L){

Linklist head,s;
head=L->next;
printf("free is successful\n");
while(head->next!=NULL){
 s=head;
 head=head->next;
 free(s);
 }

L->next=NULL;
printf("free is successful\n");

}


//插入到表头,每次插入一个节点,头结点里面的data加1
void init_start_biao(Linklist L,Linklist iner){
 iner->next=L->next;
 L->next=iner;
 L->data++;
}

//插入尾结点
void init_end_biao(Linklist L,Linklist iner){
 Linklist s;
 int i;
 s=L;
 for(i=1;i<=L->data;i++){s=s->next;}
 iner->next=s->next;
 s->next=iner;
 L->data++; 
 }

//在链表中的第i个位置插入结点
Elemt init_i_biao(Linklist L,int i,Linklist iner){
 Linklist m;
 int c;
 m=L;
 
 c=i-1;
 //m=m->nex;
 if(i<1 || i>L->data){ printf("your i is error\n");return ERROR;}

 while(c--){m=m->next;}

 iner->next=m->next;
 m->next=iner;
 L->data++;
 return OK;
}

//遍历链表中的所有元素,此法需要依赖,在头结点中存放链表中的长度
void bianli_biao(Linklist L){
 Linklist m;
 int i;
 m=L;
 printf("..........................\n");
 for(i=1;i<=L->data;i++){
 m=m->next;
 printf("%d\n",m->data);
  }

 printf("..........................\n"); 

}

//不需要参考头结点中的数(表示链表中的所有结点个数)
void bian_li(Linklist L){
 Linklist q;
 q=L->next;
 while(q){ 
  printf("%d\n",q->data);
  q=q->next;
 }

}

//删除链表中的第i个元素(不推介使用此法,此法变量多,非常之笨拙)
Elemt del_i_biao(Linklist L,int i){
 Linklist m,p,t1;
 int c,t,j;
 c=i-1;
 j=i+1;
 m=L;
 p=L;
 if(i<1 || i>L->data){printf("your i is error:\n"); return ERROR;}
 
 if(i==1)
 {
  t1=m->next;
  m=t1->next;
  L->next=m;
  free(t1);
  L->data--;
  return OK;
 }

  if(i==L->data)
  {
   t1=m->next;
   t=1;
   while(t++ < L->data) 
    {
     m=m->next;
    }

   free(m->next);

   m->next=NULL;
  L->data--;
  return OK;
 }


 while(c--){p=p->next;}
 //free(p->next);
 while(j--){m=m->next;}
 p->next=m;
 L->data--;
 return OK;
}

//此算法为删除链表中的第i个结点(推介使用)
Elemt test(Linklist L,int i){

 Linklist p,q;
 int j=0;
 p=L;
 while(p->next && j<i-1){
 p=p->next;++j; 
 }
 
 if(!(p->next) || j>i-1) return ERROR;
 q=p->next;p->next=q->next;
 free(q);
 L->data--;
 printf("to here............\n");
 return OK;

}

 

 

/将两个递增的单链表,也按递增存放到链表L中()这是自己写的,相当的笨拙,充分调动//

void la_lb_to_List(Linklist L,Linklist la,Linklist lb){
Linklist i,j,p,q;
i=la->next;
j=lb->next;
p=L;
while(i&&j){
 //创建一个结点连接在p结点后面,p结点每一次向后一个结点
 create_jiedian_biao(p);
 p=p->next;
 if(i->data < j->data )
   {
   p->data=i->data;
   i=i->next; L->data++;
   }
 
 else if(j->data < i->data){
   p->data=j->data;
   j=j->next;
   L->data++;
    }
 else if(i->data == j->data){
   p->data=i->data;
   i=i->next;
   j=j->next;
   L->data++;


    }

   }

while(i){
 create_jiedian_biao(p);
 p=p->next;
 p->data=i->data;
 L->data++;
 i=i->next;
}
while(j){
 create_jiedian_biao(p);
 p=p->next;
 p->data=j->data;
 L->data++;
 j=j->next;
}

return OK;
}

/将两个递增的单链表,也按递增存放到链表L中//


//不动态创建结点,而是灵活的使用也用的结点(这也充分利用了单链表的特点)//
Elemt la_lb_list_test(Linklist L,Linklist la,Linklist lb){
 Linklist pa,pb,pl;
 pa=la->next;
 pb=lb->next;
 pl=L;

 while(pa && pb){
  
  if(pa->data < pb->data) { printf("to here \n");
   pl->next=pa;
   pl=pa;
   pa=pa->next;
   L->data++; }
  else if(pb->data < pa->data) { 
   pl->next=pb; 
   pl=pb; 
   pb=pb->next;
   L->data++; }
  else if(pb->data == pa->data) {
   pl->next = pa;
   pl=pa;
   pa=pa->next;
   pb=pb->next;
   L->data++; }
 }

 pl->next=pa ? pa : pb;

 return OK;
}
//不动态创建结点,而是灵活的使用也用的结点(这也充分利用了单链表的特点)//

int main(){

int n=10,e;
Linklist L,iner,la,lb;
/这里要实现将la和lb结合,顺序存放到L中/
la=(Linklist)malloc(sizeof(LNode));
printf("la............................................................\n");
creat_biao_shunxu(la,5);
lb=(Linklist)malloc(sizeof(LNode));
printf("lb............................................................\n");
creat_biao_shunxu(lb,5);


//为什么头节点的创建必须要放到主函数中才能使用
L=(Linklist)malloc(sizeof(LNode));
 L->data=0;
 L->next=NULL;
//la_lb_to_List(L,la,lb);
la_lb_list_test(L,la,lb);
/这里要实现将la和lb结合,顺序存放到L中/
//头节点必须定义在主函数内;
//逆序建立一个指定大小的链表
//creat_biao(L,10);//为什么这里可以用L也可以用&L
//s顺序建立一个指定大小的单链表
//creat_biao_shunxu(L,5);
//printf("%d\n",L->data);
//这里L不能用&L

输入你要插入的结点
//printf("input your tou:\n");

//iner=(Linklist)malloc(sizeof(LNode));
// scanf("%d",&iner->data);
// iner->next=NULL;
输入你要插入的结点

//返回链表中第i个值给e
//if(back_e_i_biao(L,6,&e))
//  printf("e is:%d\n",e);
//else{printf("not exiset the e!!!\n");}

 

//在链表的第i个位置插入数
//init_i_biao(L,3,iner);

//在链表的尾部插入数
//init_end_biao(L,iner);

//在链表的首部插入数
//init_start_biao(L,iner);

//删除链表中第i个位置的结点
//del_i_biao(L,2);

//删除链表中的第i个结点
//test(L,5);

//遍历链表(此法遍历需要通过头结点中的数(表示该链表中有多少个结点。。。。除头结点))
//bianli_biao(L);

//该遍历法,不需要通过头结点中的数,来遍历,只要知道头结点的地址就可以进行遍历
bian_li(L);
//销毁创建的链表
//destory_biao(L);
//destory_biao(la);
//destory_biao(lb);

 

return OK;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值