Chinaunix首页 | 论坛 | 博客
  • 博客访问: 770942
  • 博文数量: 370
  • 博客积分: 2334
  • 博客等级: 大尉
  • 技术积分: 3222
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-06 16:56
文章分类

全部博文(370)

文章存档

2013年(2)

2012年(368)

分类:

2012-06-09 12:23:22

原文地址:单链表算法 作者:flychenxu

1、单链表的数据结构:包括数据域和指针域

struct LinkList

{        int data;

         struct LinkList *next;

};

2、单链表的构造有前插法和后插法

(1) 前插法构造链表,输入的数据小于零则退出

struct LinkList *CreateLinkBefore()

{

         struct LinkList *head = NULL, *newNode;

         while (1)

         {

                   newNode = new struct LinkList;

                   scanf("%d", &newNode->data);

                   newNode->next = NULL;

                   if (newNode->data < 0)

                   {

                            delete newNode;

                            break;

                   }

                   if (head == NULL)    //链表为空

                   {

                            head = newNode;

                   }

                   else       //链表非空

                   {

                            newNode->next = head;

                            head = newNode;

                   }

         }

         return head;

}

(2) 后插法构造链表

struct LinkList *CreateLinkListAfter()

{

         struct LinkList *head, *tail, *newNode;

         head = tail = NULL;

         while (1)

         {

                   newNode = new struct LinkList;

                   scanf("%d", &newNode->data);

                   newNode->next = NULL;

                   if (newNode->data < 0)

                   {

                            delete newNode;

                            break;

                   }

                   if (head == NULL)  //链表为空

                   {

                            head = tail = newNode;

                   }

                   else

                   {

                            tail->next = newNode;

                            tail = newNode;

                   }

         }

         return head;

}

3 链表长度计算

int GetLinkListLen(struct LinkList *head)

{

         int len = 0;

         struct LinkList *p = head;

         while (p)

         {

                   len++;

                   p = p->next;

         }

         return len;

}

4 遍历链表中的数据

void PrintLinkList(struct LinkList *head)

{

         struct LinkList *p = head;

         while (p != NULL)

         {

                   printf("%d ", p->data);

                   p = p->next;

         }

         printf("\n");

}

5 释放链表空间:从头结点开始往后删,在删除前一个节点前,必须将下一个节点的地址保存。

void FreeLinkList(struct LinkList *head)

{

         while (head != NULL)

         {

                   struct LinkList *p = head; 

                   head = p->next;  

                   delete p;

         }

}

6 删除链表中第一个值为num的节点

struct LinkList *DelLinkList(struct LinkList *head, int value)

{

         struct LinkList *p,*pre;

         p = head;

         if (p != NULL)

         {

                   while (p->data != value && p->next != NULL)

                   {

                            pre = p;

                            p = p->next;        

                   }

                   if (p->data == value)

                   {

                            if (p == head)  //删除的节点为头结点

                            {

                                     head = p->next;

                                     delete p;

                            }

                            else

                            {

                                     pre->next = p->next;

                                     delete p;

                            }

                   }

                   else

                   {

                            printf("there is no record's value is equal to %d\n", value);

                   }

         }

         return head;

}

7 插入元素到链表

struct LinkList *InsertLinkList(struct LinkList *head, int value)

{

         struct LinkList *newNode, *pre, *p;

         p = head;

         newNode = new struct LinkList;

         newNode->data = value;

         if (p)

         {

                   while (newNode->data > p->data && p->next != NULL)

                   {

                            pre = p;

                            p = p->next;

                   }

                   if (newNode->data <= p->data)

                   {

                            if (p == head)  //插入的节点值比小于等于头结点的值

                            {

                                     newNode->next = p;

                                     head = newNode;

                            }

                            else   //插入的节点位置在中间位置

                            {

                                     newNode->next = p;

                                     pre->next = newNode;

                            }

                   }

                   else   //插入节点值大于尾节点,即插入在链表尾部

                   {

                            p->next = newNode;

                            newNode->next = NULL;

                   }

         }

         return head;

}

8链表元素逆置有两种方法非递归与递归

(1) 链表元素逆置的非递归

struct LinkList *ReverseLinkList(struct LinkList *head)

{

         struct LinkList *p1, *p2, *p3;

         p1 = head;

         if (p1 == NULL || p1->next == NULL)

         {

                   return head;

         }

         p2 = p1->next;

         while (p2)

         {

                   p3 = p2->next;

                   p2->next = p1;

                   p1 = p2;

                   p2 = p3;

         }       

         head->next = NULL;

         head = p1;

         return head;

}

(2) 链表元素逆置,递归实现

struct LinkList *ReverseLinkListDiGui(struct LinkList *&head, struct LinkList *p)

{

         if (p == NULL || p->next == NULL)

         {

                   head->next = NULL;

                   head = p;

                   return p;

         }

         else

         {

                   struct LinkList *tmp = ReverseLinkListDiGui(head, p->next);

                   tmp->next = p;

                   return p;

         }

}

9、判断链表中是否有环,其基本思想是设两个指针从同一个位置出发,一个指针一次前进一步,另外一个指针一次前进两步, 如果链表中存在环,则经过一定的移动后,两个指针一定会再次在某个节点相遇.

bool CirCleLinkList(struct LinkList *head)

{

         if (head == NULL || head->next == NULL)

         {        return false;      }

         else

         {

                   struct LinkList *p1, *p2;

                   p1 = p2 = head;

                   do

                   {

                            p1 = p1->next;

                            p2 = p2->next->next;

                   }while(p2 != NULL && p2->next != NULL && p1 != p2);

                   if (p1 == p2)

                            return true;

                   else

                            return false;

         }

}

10、已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)

非递归:

 

  1. struct LinkList *MergeList(struct LinkList *head1, struct LinkList *head2)
  2. {
  3.     struct LinkList *head =NULL, *p1 = NULL, *p2 = NULL, *cur = NULL;
  4.     if (head1 == NULL)
  5.     {
  6.         return head2;
  7.     }
  8.     if (head2 == NULL)
  9.     {
  10.         return head1;
  11.     }

  12.     if (head1->data <= head2->data)
  13.     {
  14.         head = head1;
  15.         p1 = head1->next;
  16.         p2 = head2;
  17.     }
  18.     else
  19.     {
  20.         head = head2;
  21.         p2 = head2->next;
  22.         p1 = head1;
  23.     }
  24.     cur = head;
  25.     while (p1 != NULL && p2 != NULL)
  26.     {
  27.         if (p1->data <= p2->data)
  28.         {
  29.             cur->next = p1;
  30.             cur = p1;
  31.             p1 = p1->next;
  32.         }
  33.         else
  34.         {
  35.             cur->next = p2;
  36.             cur = p2;
  37.             p2 = p2->next;
  38.         }
  39.     }
  40.     if (p1 != NULL)
  41.     {
  42.         cur->next = p1;
  43.     }
  44.     if (p2 != NULL)
  45.     {
  46.         cur->next = p2;
  47.     }

  48.     return head;
  49. }
递归:
  1. struct LinkList *MergeList2(struct LinkList *head1, struct LinkList *head2)
  2. {
  3.     if (head1 == NULL)
  4.         return head2;
  5.     if (head2 == NULL)
  6.         return head1;
  7.     struct LinkList *head = NULL;
  8.     if (head1->data <= head2->data)
  9.     {
  10.         head = head1;
  11.         head->next = MergeList2(head1->next, head2);
  12.     }
  13.     else
  14.     {
  15.         head = head2;
  16.         head->next = MergeList2(head1, head2->next);
  17.     }
  18.     return head;
  19. }
阅读(464) | 评论(0) | 转发(0) |
0

上一篇:双链表算法

下一篇:循环队列基本操作

给主人留下些什么吧!~~