码迷,mamicode.com
首页 > 其他好文 > 详细

关于链表的函数的实现

时间:2015-04-24 22:25:42      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:

 

链表是由一个个节点组成的,每个节点中都存储有一个指向下一个节点的指针。所以在创建链表的时候最好先写一个结构体,用来创建每一个节点。

例如:

         typedef struct node

        {

             char name[20];// 开辟空间

             struct node* next;

         }Student;

 

1.创建链表:       

                Student* creatList(int n)

                {

                           Student * head = new Student;

                           head -> next = NULL;

                           Student* pre = head;//记录新节点的前一个节点

                           cout<<" input name: ";

                           for (int i = 0; i < n; i++) {

                                      Student* p = new Student;

                                      cin>>p->name;

                                      pre->next = p;

                                      p->next = NULL;

                                      pre = p;//重新改变pre的值

                             }

                    return head;

             }

2.添加节点:

添加节点和删除节点之前可以先把链表的长度求出来,用起来比较方便。

                      int length(Student *head)

                      {

                                   int i = 0;

                                   Student * p = head->next;

                                   while (p != NULL) {

                                               i++;

                                               p = p->next;

                                      }

                                      return i;

                          }

  

                          void addElement(Student* head, char* str, int index)

                          {

                                       Student* p = head;

                                       int len = length(head);

                                       if (index<0||index>len+1) {           //判断是否越界

                                                cout<<"请重新输入:"<<endl;

                                                return;

                                       }

                                       for (int i = 1; i<index; i++) {          //找到需要插入位置的前一个位置的节点

                                                 p = p->next;

                                        }

                             Student* news = new Student;

                             strcpy(news->name, str);

                             news->next = p->next;              //让新节点的指针指向他前一个节点原本指向的节点

                             p->next = news;                        //让新节点的前一个节点的指针指向新节点

                   }

 

3. 删除节点

                 void removeElement(Student* head, int index)

                 {

                            Student* p = head;

                            int len = length(head);

                            if (index>len||index<0) {                         //判断要移除的节点的下标是否越界

                                     cout<<"请重新输入:"<<endl;

                                     return;

                             }

                             for (int i = 1; i < index; i++) {              //找到要移除的节点的前一个节点

                                     p = p->next;

                             }

                             Student* tmp = p->next  ;               //让指针tmp指向要移除的节点

                             p->next = tmp->next;                     //要移除节点的前一个节点的指针指向要移除节点的后一个节点

                             delete tmp;

                   }

 4. 逆序输出链表

                  Node* reverse(Node* head)

                  {

                           if (head->next == NULL) {

                                   return head;

                           }

                           else{

                                   Node* p = head->next;

                                   Node* q = head->next;

                                   Node* t = NULL;

                                   while (q != NULL) {

                                            p = q->next;

                                            q->next = t;

                                            t = q;

                                            q = p;

                                    }

                                    p = new Node;

                                    p->next = t;

                                    q = p;

                                    return q;

                         }

                }

        备注:主要思想就是用三个指针依次改变链表节点的指向,达到反序的目的。

 

5. 合并链表(两个链表分别有序,要求合成的链表依然有序)

               //非递归合并链表

               Node* hebingList(Node* head1, Node* head2)

               {

                         Node* pa = NULL;

                         Node* pb = NULL;

                         if (head1->next != NULL) {

                                    pa = head1->next;

                         }

                         else{

                                    return head2;

                         }

                        if (head2->next != NULL) {

                                    pb = head2->next;

                        }

                        else{

                                    return head1;

                        }

                        Node * head = head1;

                        Node * t = head;

                        while (pa != NULL && pb != NULL) {

                                    if (pa->data >= pb->data) {

                                               t->next = pb;

                                               t = pb;

                                               pb = pb->next;

                                     }

                                     else{

                                                t->next = pa;

                                                t = pa;

                                                pa = pa->next;

                                     }

                           }

                           if (pa != NULL) {

                                     t->next = pa;

                            }

                           if (pb != NULL) {

                                     t->next = pb;

                           }

                           return head;

                 }

                //递归合并链表

                Node * MergeRecursive(Node *head1 , Node *head2)

                {

                           if ( head1 == NULL )

                                     return head2 ;

                           if ( head2 == NULL)

                                     return head1 ;

                           Node *head = NULL ;

                           if ( head1->data < head2->data )

                           {

                                     head = head1 ;

                                     head->next = MergeRecursive(head1->next,head2);

                            }

                           else

                           {

                                     head = head2 ;

                                     head->next = MergeRecursive(head1,head2->next);

                            }

                            return head ;

                 }

 

 链表这一块如果单单用脑子想可能会稍微复杂点,但是可以把图画出来,就一目了然。

 

 

6. 最后说一个忘了是哪里的面试题,关于链表的,感觉也挺经典的。

     题目是:有一百个球,每个球上都有编号,按顺序排列,每次取出偶数位置上的球,求最后一个剩余的球原来的编号是多少?

     想来想去,也就用链表来解这道题比较简单一些。

     具体实现代码如下:

              typedef struct node{

                       int num;

                       struct node* next;

              }Ball;

              int length(Ball* head){

                       int i = 0;

                       Ball* p = head->next;

                       while (p != NULL) {

                                  i++;

                                  p = p->next;

                       }

                       return i;

               }

               Ball* creatList(int n){                        

                        Ball* head = new Ball;

                        head->next = NULL;

                        Ball* pre = head;

                        for (int i = 0; i < n; i++) {

                                   Ball* p = new Ball;

                                   p->num = i+1;

                                   pre->next = p;

                                   p->next = NULL;

                                   pre = p;

                         }

                         return head;

                 }

                 void remove(Ball* head){

                           Ball* p = head;

                           int s = length(head);

                           while (length(head)>=2){

                                       if (length(head)%2 == 0) {

                                                     for (int i = 0; i < s/2; i++) {

                                                                  Ball* tmp = p->next;

                                                                  p->next = tmp->next;

                                                                  delete tmp;

                                                                  p = p->next;

                                                       }

                                        }

                                        else{

                                                       for (int i = 0; i < (int)s/2-1; i++) {

                                                                   Ball* tmp = p->next;

                                                                   p->next = tmp->next;

                                                                   delete tmp;

                                                                   p = p->next;

                                                        }

                                                        delete p->next;

                                                        p->next = NULL;

                                           }

                                           p = head;

                                           s/=2;

                                 }

                      }

 

关于链表的函数的实现

标签:

原文地址:http://www.cnblogs.com/benniuniu-gj/p/4454612.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!