单链表的创建(头插尾插),表长,输出,插入,删除,查找,逆置,分解长两个链表(奇数偶数链表),查找倒数第k个元素,产出相同元素

//暂时没有什么事情,这段时间准备把数据结构上东西都实现以下

#include<stdio.h>

#include<stdlib.h>
#include<malloc.h>
typedef struct ListNode
{
int data;
struct ListNode *next;
} ListNode,*pListNode;




pListNode  createFromHead(int len) ; //头插法
pListNode  createFromTail(int len) ; //尾插法
int listLen(pListNode head) ;


void insert(pListNode * head,int i,int data);
void delete(pListNode * head,int i, int * x);
void search(pListNode head,int x,int * location);
pListNode FindKthFromTail(pListNode p, int k) ;
void divisionList(pListNode head);
void print(pListNode head) ;
void destroy(pListNode head) ;
void deleteCommon(pListNode head) ;
void reverse(pListNode *head);  //不重新申请新结点,进行链表逆置



/*


   在链表中查找符合要求的第一个元素,并返回它在链表的位置
 */
void  search(pListNode head,int x,int * location)
{
if( !head)
printf("list is null");
//debug("parameter is null\n");
pListNode p=head;
int i=1;
while(p)
{
if( p->data ==x)
{
*location=i;
printf("search %d in the %dth location .Success\n",x,i); 
return ;
}
else
{
p=p->next;
i++;
}   



if(p==NULL)
printf("don't have the num: %d. Fail.\n",x);


}


pListNode insert_1(pListNode head,int i,int data)  //此函数带返回头指针的插入,调用需要head=insert_1(head,i,data);因为当插入第一个结点时,头指针被修改了
{
pListNode p=head;
int j=0;
if(!head)
printf("list is null\n");
if(i<=0)
{
printf("the input i is not true\n");
return head; 
}


if( i>listLen(head) )
{
printf("the location you insert is longer than the list's length\n");
return head;
}
else 
{
pListNode p1=NULL;
if(i==1)
{
p1=(pListNode ) malloc( sizeof(ListNode));
p1->data=data;
p1->next=p;
head=p1;  // 这里尤其要注意,因为是修改形参,它的值时是无法改变实参,即如果函数用void指针是带不出去的,
//因为形参只是实参的一份拷贝,所以指针指向的内容是一致的,即修改的值可以带出去,但是地址带不出去,所以
//可以采用两种方案,第一函数返回值用pListNode(推荐使用), 第二种采用二级指针
printf("insert the %d in the %dth location. Success\n",p1->data,i);
return head;


}  
else
{
for(j=1;j<i-1;j++)  //i节点的前驱,由于头结点和第一个节点的位置一样所以是后移i-2,如果头结点是不是第一个节点,则后移i-1
p=p->next;
p1=(pListNode ) malloc( sizeof(ListNode));
p1->data=data;
p1->next=p->next;
p->next=p1;
printf("insert the %d in the %dth location. Success\n",p1->data,i);
return head;
}  
}  


}












/*
   注:上面的插入方案也可以,不过需要返回值,在main中每次都head=insert(head,i,data)太麻烦所以采用二级指针
 */
void insert(pListNode * head,int i,int data)
{
pListNode p=*head;
int j=0;
if(! *head)
printf("list is null\n");
if(i<=0)
{
printf("the input i is not true\n");


}


if( i>listLen(*head) )
{
printf("the location you insert is longer than the list's length\n");


}
else 
{


pListNode p1=(pListNode ) malloc( sizeof(ListNode));
p1->data=data;
if(i==1)
{
p1->next=p;
*head=p1;  
printf("insert the %d in the %dth location. Success\n",p1->data,i);


}  
else
{
for(j=1;j<i-1;j++) 
p=p->next;
p1->next=p->next;
p->next=p1;
printf("insert the %d in the %dth location. Success\n",p1->data,i);


}  
}  


}


void delete(pListNode * head,int i, int * x)
{
if( i<=0 || i>listLen(*head) )
fprintf(stderr,"the input is error\n");
else
{
pListNode p=*head;
if(!p)
{
printf("the list is null\n");
return ;
}
if(i==1)
{
*x=p->data;
*head=p->next;
free(p);
}
else
{
int j=1;
for( ;j<i-1;j++)  //走i-2,由于头指针指向第一个节点
{
p=p->next; 


}
pListNode p1=p->next;
*x=p1->data;
p->next=p->next->next; 
free( p1);  
}
printf("delete the %dth location. Success\n",i);       


}
}
int listLen(pListNode head)

int len=0;
pListNode p=head;
while(p)
{
len++;
p=p->next;
}


printf("listLen is %d \n",len);
return len;


}


pListNode  createFromHead(int len) //头插法
{
pListNode head=NULL;
if(len<0)
fprintf(stderr,"len is error\n");
else if(len==0)
return (pListNode )NULL;
else
{
pListNode p1=NULL;
pListNode p=NULL;
while(len)
{
p=(pListNode) malloc(sizeof( ListNode) );
scanf("%d", & (p->data) );
p->next=p1;
p1=p;
len--;
}
head=p;
}
return head;  


}


pListNode  createFromTail(int len)
{
pListNode head=NULL;
if(len<0)
fprintf(stderr,"len is error\n");
else if(len==0)
return (pListNode) NULL;
else
{






pListNode p1=NULL;
pListNode p2=NULL;
p2=(pListNode) malloc( sizeof(ListNode) );
scanf("%d",& (p2->data));
p2->next=NULL;
p1=p2;
head=p1;
len--;
while(len)
{
p2=(pListNode) malloc( sizeof(ListNode) );
scanf("%d",& (p2->data) );
p2->next=NULL;
p1->next=p2;
p1=p2;
len--;
}
}   


return head;
}
void destroy(pListNode head)
{
pListNode pre=head;
pListNode cur=pre;
while(cur)
{
cur=cur->next;
free(pre);
pre=cur;


}
}


void print(pListNode head)
{
pListNode p=head ;
if(head==NULL)
{
printf("list is null\n");
exit(-1);
}
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n\n");
}




pListNode FindKthFromTail(pListNode head, int k)
{
pListNode p= head;
if(!p)
{
printf("parameter is null\n");
exit(-1);
}
if(k<=0)
{
printf("the input k is not illgeal\n");
exit(-1);
}
if( k>listLen(p) )
{
printf("%d is longer than the  list\n",k);
exit(-1);
}


int i;
for(i=0  ;i <k ;i++)
p=p->next;
pListNode q=head;
while(p!=NULL)
{
p=p->next;
q=q->next; 


}


return q; 


}


void reverse(pListNode *head)
{
pListNode p=*head;
if(p==NULL)
{
printf("list is null \n");
exit(-1);
return ;
}
pListNode p1=p->next;
if( p1==NULL)
return ;


pListNode p2=p1->next;
if(p2==NULL)
{
p->next=NULL;
p1->next=p ;
*head=p1;
return ;
}


p->next=NULL;
while(p2)
{
p1->next=p;
p=p1;
p1=p2;
p2=p2->next;
}
p1->next=p;
*head=p1;


}


/*
   void divisionList( pListNode head, pListNode *podd,pListNode *peven)
   {
   if(!head)
   {
   fprintf(stderr,"list is null\n");
   exit(-1);
   }
   int count1=0;
   int count2=0;
   pListNode p=head;
   pListNode p1=( pListNode ) malloc(sizeof(ListNode));
 *podd=p1;
 (*podd)->next=NULL;
 pListNode p2=(pListNode ) malloc(sizeof ( ListNode)) ;
 *peven=p2;
 (*peven)->next=NULL;


 while( p)
 {
 if(p->data %2)
 {
 p1->next=p;   
 count1++;        
 }
 else
 {
 p2->next=p;
 count2++;
 }
 }
 p1->next=NULL;
 p2->next=NULL;
 (*podd)->data=count1;
 (*peven)->data=count2;
 }
 */






void divisionList(pListNode head)
{
if(!head)
{
fprintf(stderr,"list is null\n");
exit(-1);
}
int count1=0;
int count2=0;
pListNode p=head;
pListNode p1=( pListNode ) malloc(sizeof(ListNode));
pListNode podd=p1 ;
p1->next=NULL;
pListNode p2=(pListNode ) malloc(sizeof ( ListNode)) ;
pListNode peven=p2;
p2->next=NULL;


while( p)
{
if(p->data %2)
{
p1->next=p;   
p1=p;
count1++;        
}
else
{
p2->next=p;
p2=p;
count2++;
}
p=p->next;
}
p1->next=NULL;
p2->next=NULL;
podd->data=count1;
peven->data=count2;
printf("odd is  %d个 ",podd->data);
print(podd->next);  //由于此时带头结点
printf("even is %d个 ",peven->data);
print(peven->next);
destroy(podd);
destroy(peven);
}


void deleteCommon(pListNode head)  
{
pListNode p=head;
if(!p)
{
printf("the list is null\n");
return ;
}
pListNode pre=p;
pListNode cur=pre->next;
if( !cur)
return ;//只有一个结点,一定不会出现相同元素
if(!cur->next )  //只有两个结点时要特殊处理,出现这种问题的本质原因在于链表结构设计的不合理,应该采用带有头指针的单链表
{
if(pre->data==cur->data)
free(cur);
return ;
}
pListNode runner=p;
while( cur)
{
runner=p;
while(runner!=cur)
{
if(runner->data ==cur->data )
{
cur=cur->next;
free(pre->next);
pre->next=cur;
break;
}
else
{
runner=runner->next;
}
}


if(runner==cur)
{
pre=cur;
cur=cur->next;
}
}


}


int main()
{
int len,k;
scanf("%d %d ", &len ,&k);
/*
  pListNode head= createFromHead(len);
  print(head);
  print(head);


  insert(& head,3,11);
  print(head);


  insert(& head,12,100);
  print(head);
  pListNode p= FindKthFromTail(head,k);
  printf("find kth is %d\n",p->data);
  destroy(head);
*/


pListNode headT= createFromTail(len);
print(headT);
insert(& headT,1,9);//insert(head,1,9)指针带不出来,也可以使用二级指针
print(headT);


insert(& headT,3,11);
print(headT);
int a;
delete(& headT,2, &a);
printf("the delete is %d \n",a);
insert(& headT,12,100);
int i;
search(headT,4,&i);
print(headT);
pListNode p= FindKthFromTail(headT,k);
printf("find kth is %d\n",p->data);
reverse(&headT);
print(headT);


deleteCommon(headT);
print(headT);
// pListNode podd,peven;
// divisionList(headT,&podd,&peven);
divisionList(headT);
// podd=podd->next;
//peven=peven->next;
// print(podd);
// print(peven);
//destroy(headT);
return 1;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值