单链表的一些练习题

   本来准备自己写一个单链表的排序,但是没写出来,原因是不知道怎么判断最外层的循环结束条件。只好参考网上的例子了,参考链接:http://blog.csdn.net/wzy_1988/article/details/8129505,另外我感觉以下两种法案不是最优解

    1.当然如果是先求链表长度 n=length(head);,这样的for(i=0;i<n;i++)外部循环,感觉就没啥意思了

    2.还有就是一种只交换链表中两个结点的data值,而不是交换两个结点,对于这种,我感觉如果只有一个成员变量data还行,如果这个结构体里面的成员变量有若干个,这样能行吗?

   下面的代码是正解,其实这个循环退出条件就是每次冒泡排完一个数之后,就让tail指针指向有序结点,比如6 5 4 3 2 1,那么指向的顺序是6,5,4,3,2

struct LinkList * bubbleSort(struct LinkList *head){
   if(head==NULL||head->next==NULL) return NULL;
   struct LinkList *tmp=head,*tail=NULL;
   struct LinkList *p,*q;
   while(head->next->next!=tail){
      for(p=head;p->next->next!=tail;p=p->next){
         if(p->next->data>p->next->next->data){
              q=p->next;
              p->next=q->next;
              q->next=p->next->next;
              p->next->next=q;
         }
      }
      tail=p->next;
   }
   return head;
}

当然单链表还有很多很有意思的题,参考链接:http://kofsky.iteye.com/blog/283250

1.怎么判断链表中是否有环? 

2.给你一个单向循环链表,怎么找出这个链表循环部分的第一个节点?

3.链表逆序?

4.一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?

5.给定一个链表的头指针,在一次遍历中,找出这个链表中的中间节点并返回。

6.查找链表中倒数第k个节点(只允许遍历链表一次)

7.编写实现链表排序的一种算法

8.找两个链表的第一个公共节点


其中1,3,5,7都已实现,在以后我会陆续实现6中的归并两个链表排序,7,8等算法

2.给你一个单向循环链表,怎么找出这个链表循环部分的第一个节点?
跟第一个略有不同。第一个只是判断是否有环,而这个是要找出第一个节点。
标记法不错。hash也可以,貌似

4.一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点? 
把next节点的key区域复制到本节点,然后删除next节点

6.查找链表中倒数第k个节点
两个指针,保持距离k

8.找两个链表的第一个公共节点
如果有公共节点,那么该节点后面的节点全部都是两链表公共部分。


以下实现代码参考链接:http://www.cppblog.com/koson/archive/2010/04/21/113142.aspx

下面的代码都是直接copy的,但是看一眼就明白了,感觉思路知道了,代码应该没啥问题

找到链表的中间结点(感觉这个思路很巧妙,代码非常简单,其实找到链表的中间节点,判断链表是否有环,找到链表的倒数第k各结点的都是思路难,而代码易,且这三道题的思路类似,都是用两个指针,巧妙的运用这两个指针的"距离"来解题)

  LinkList* findMiddle(LinkList* head){
      ListNode *p1, *p2;
     if (head == NULL || head->next == NULL)  {
        return head;
      }
      p1 = p2 = head;
     while (1){
         if (p2->next != NULL && p2->next->next != NULL){
             p2 = p2->next->next;
             p1 = p1->next;
         }
         else {
             break;
         }
     }
     return p1;
 }

判断链表是否有环

 int isLoop(LinkList *head){
      ListNode *p1, *p2;
      p1 = p2 = head;
      if (head == NULL || head->next == NULL){
         return 0;
      }
     while (p2->next != NULL && p2->next->next != NULL){
         p1 = p1->next;
         p2 = p2->next->next;
         if (p1 == p2){
             return 1;
        }
     }
     return 0;
 }


未完待续:下一节 链表算法三之静态链表

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值