zoukankan      html  css  js  c++  java
  • 单向链表

    链表的操作不外乎 增 删 改 查 还能有个额外的打印

    1. 头插 , 2.尾插 , 3.中端插入  4.头删  5.尾删 6.中段删除  7.查 8. 改  9.反转打印   10.反转链表   11.判断链表是否有环    12.合并两个有序链表   13.链表排序(选择)

    链表节点结构

     1 typedef struct _T_LINKNODE{ 2 int data; 3 _T_LINKNODE* pNext; 4 }T_LINKNODE, *PT_LNode; 

    创建节点并初始化

     1 PT_LNode creadNode()        //创建节点
     2 {
     3     PT_LNode pNew = (PT_LNode)malloc(sizeof(T_LINKNODE));
     4     init(pNew);
     5     return pNew;
     6 }
     7 
     8 void init(PT_LNode pHead)    //初始化
     9 {
    10     pHead->data = 0;
    11     pHead->pNext = NULL;
    12 }

    增 : 头插 尾插  和查找插入 头节点可以用于计数节点个数

    1.头插: 新节点的next  指向头节点的next   头节点的next指向新节点  

     1 int insertHead(PT_LNode pHead, int data) //头插 头节点计数
     2 {
     3   if (isEmpty(pHead))
     4   {
     5     insertBack(pHead, data);
     6     return ++(pHead->data);
     7   }
     8   else
     9   {
    10     PT_LNode pNew = creadNode();
    11     pNew->data = data;
    12     pNew->pNext = pHead->pNext;
    13     pHead->pNext = pNew;
    14     return ++(pHead->data);
    15   }
    16 }

    2.尾插: 创建一个同链表的结构一样的类型指针(不需要malloc)  利用循环找到next指向NULL的指针 , 把指向NULL的指针指向新节点 完成插入.

     1 int insertBack(PT_LNode pHead, int data) //尾插 头节点计数
     2 {
     3   PT_LNode p = pHead;
     4   while (p->pNext)
     5   {
     6     p = p->pNext;
     7   }
     8   PT_LNode pNew = creadNode();
     9   pNew->data = data;
    10   p->pNext = pNew;
    11   return ++(pHead->data);
    12 }

    3.查找插入: 先判断要查找的数据是否存在 ,可以利用查找函数返回的指针用作插入 (特殊情况 , 如果满足头插和尾插的条件可以分别调用写好函数插入) 

     1 int insertNode(PT_LNode pHead, int Fdata, int newData)        
     2 {
     3     
     4     PT_LNode tempNode = findData(pHead, Fdata);      //findData在下面
     5 
     6     PT_LNode pNew = creadNode();
     7     pNew->data = newData;
     8     if ((!tempNode->pNext) && (tempNode->data  == Fdata))
     9     {
    10         insertBack(pHead, newData);
    11     }
    12     else
    13     {
    14         pNew->pNext = tempNode->pNext;
    15         tempNode->pNext = pNew;
    16         return ++(pHead->data);
    17     }
    18 }

    删除节点 , 和插入一 一对应 删除的数据返回出来以备不时之需

    4.头删除: 使用临时指针 指向要删除的节点 头指针再指向删除节点的next重新链接链表 

     1 int deleteHead(PT_LNode pHead)
     2 {
     3   int temp;
     4   PT_LNode p = pHead->pNext;
     5   pHead->pNext = p->pNext;
     6   temp = p->data;
     7   free(p);
     8   p = NULL;
     9   --pHead->data;
    10   return temp;    
    11 }

    5.尾删除: 利用循环找到末尾的上一个节点 直接free掉末尾 , 末尾的上一个节点指向NULL

     1 int deleteBack(PT_LNode pHead)
     2 {
     3   int temp;
     4   PT_LNode p = pHead; 
     5   while (p->pNext->pNext)
     6   { 
     7     p = p->pNext;
     8   }
     9   temp = p->pNext->data;
    10   free(p->pNext);
    11   p->pNext = NULL;
    12   --pHead->data;
    13   return temp;
    14 }

    6.查找删除节点: 找到要删除的当前节点的上一个节点 , 用一个临时节点指向当前节点 , 把当前节点的上一个节点 指向 当前节点的下一个节点 , 再free掉临时节点置空

     1 int deleteNode(PT_LNode pHead, int deleteData)
     2 {
     3     int temp;
     4     PT_LNode p = pHead->pNext;
     5     if (p == pHead->pNext && p->data == deleteData)
     6     {
     7         return deleteHead(pHead);
     8     }
     9     while (p->pNext)
    10     {
    11         if (p->pNext->data == deleteData)
    12         {
    13             break;
    14         }
    15         p = p->pNext;
    16     }
    17     if ((!p->pNext) && (p->data == deleteData))
    18     {
    19         return deleteBack(pHead);
    20     }
    21     else
    22     {
    23         PT_LNode pTemp = p->pNext;
    24         p->pNext = pTemp->pNext;
    25         temp = pTemp->data;
    26         free(pTemp);
    27         pTemp->pNext = NULL;
    28         --pHead->data;
    29         return temp;
    30     }
    31 }

    7.改之前先查: 遍历所有节点 找到符合条件的节点(要找的数据节点)并返回指向要找节点的指针

     1 PT_LNode findData(PT_LNode pHead, int Fdata)    //返回要查找数据的指针
     2 {
     3     PT_LNode p = pHead;
     4     bool flag = true;
     5     while (p->pNext)
     6     {
     7         if (p->data == Fdata)
     8         {
     9             break;
    10         }
    11         else
    12         {
    13             p = p->pNext;
    14         }
    15     }
    16     (!p->pNext) && (p->data != Fdata) ? flag = false : flag;
    17     if (flag)
    18     {
    19         printf("要查找的数据存在
    ");
    20         return p;
    21     }
    22     else
    23     {
    24         printf("要查找的数据不存在
    ");
    25         return NULL;
    26     }
    27 }

    8.改: 利用查找函数返回的指针赋值

     1 void changeData(PT_LNode pHead, int Fdata, int newData)
     2 {
     3     PT_LNode pTemp = findData(pHead, Fdata);
     4     if (!pTemp)
     5     {
     6         printf("数据不存在
    ");
     7         return ;
     8     }
     9     else
    10     {
    11         pTemp->data = newData;
    12     }
    13 }

    9.反转打印(递归法)

    1 void reversalPrint(PT_LNode pHead)
    2 {
    3     if (!pHead)
    4     {
    5         return;
    6     }
    7     reversalPrint(pHead->pNext);
    8     printf("%d<-", pHead->data);
    9 }

    10.反转链表(递归法) : 递归逐层进入到最里层(递归边界 next == NULL) 再从最里层的next开始逐层向外指后 , 

    当前节点制空 并 返回指向当前层的指针(当前节点是pHead)         

     1 PT_LNode reversalList(PT_LNode pHead)
     2 {
     3     if (!pHead->pNext || !pHead)
     4     {
     5         return pHead;    
     6 
     7     }    
     8     PT_LNode pTemp = reversalList(pHead->pNext);  //传入当前节点pHead进入递归 并 另存当前节点
     9     pHead->pNext->pNext = pHead;           //当前节点指向上一个节点
    10     pHead->pNext = NULL;                //把上一个节点制空
    11     return pTemp;                    //返回当前节点 , 用作上一层递归
    12 }

    11.判断单链表是否有环  用两个指针都指向头节点 , 从第一个开始p1每次都比p2快一个节点 , 如果有环则会相遇 

     1 bool judgeCircle(PT_LNode pHead)
     2 {
     3     PT_LNode p1, p2;
     4     p1 = pHead;    p2 = pHead;
     5     while (p1->pNext && p2->pNext)
     6     {
     7         
     8         p2 = p2->pNext;
     9         p1 = p1->pNext->pNext;
    10         if (p1 == p2)
    11         {
    12             return true;
    13         }
    14     }
    15     return false;
    16 }

     12.合并两个有序递增的链表: 1对1   2对2  的比较大小 , 小的先插入新链表以此类推 ,因为链表是有序递增的 比较剩下的一定比插入好的大

                所以依次插入新链表

     1 PT_LNode mergeList(PT_LNode pHead3, PT_LNode pHead1, PT_LNode pHead2)
     2 {
     3     PT_LNode p1 = pHead1;
     4     PT_LNode p2 = pHead2;
     5     while (p1 || p2)    //必须两个链表都遍历完
     6     {
     7         if (p1 && p2)    
     8         {
     9             if (p1->data < p2->data)  //1对1 2对2 彼此对应比较 较小的放前面
    10             {
    11                 insertBack(pHead3, p1->data);
    12                 p1 = p1->pNext;
    13             }
    14             else
    15             {
    16                 insertBack(pHead3, p2->data);
    17                 p2 = p2->pNext;
    18             }
    19         }
    20         else        //链表节点数量不相同 , 则把后面的都插入 , 因为是链表已经是有序的 , 前面比较都是比后面的小 , 所以剩余的节点全部依次插入新链表
    21         {
    22             while (p1)
    23             {
    24                 insertBack(pHead3, p1->data);
    25                 p1 = p1->pNext;
    26             }
    27             while (p2)
    28             {
    29                 insertBack(pHead3, p2->data);
    30                 p2 = p2->pNext;
    31             }
    32             break;      //链表遍历完成 退出遍历
    33         }
    34     }
    35     return pHead3;    //返回新链表
    36 }

     13.链表的排序(选择)  : p1第一次循环把第一个数据和后面的全部一 一比较(满足条件交换)    p1第二次循环把第二个和后面都比较,以此类推 时间复杂度O(n^2)

     1 void ListSort(PT_LNode pHead)
     2 {
     3     PT_LNode p1, p2;
     4     int temp;
     5     for (p1 = pHead->pNext; p1->pNext; p1 = p1->pNext)
     6     {
     7         for (p2 = p1->pNext; p2; p2 = p2->pNext)
     8         {
     9             if (p1->data > p2->data)
    10             {
    11                 temp = p1->data;
    12                 p1->data = p2->data;
    13                 p2->data = temp;
    14             }
    15         }
    16     }
    17 }
  • 相关阅读:
    Android 多线程 打地鼠游戏
    Android 线程那些事儿
    Android 服务入门
    Android+Handler+Thread 那些事儿
    Android 数据库的线程合作
    Android 数据库中的数据给到ListView
    git 修改管理
    import com.sun.image.codec.jpeg.JPEGCodec不通过 找不到包(转载)
    VC++中开发汇编语言(转)
    C struct结构体内存对齐问题
  • 原文地址:https://www.cnblogs.com/yxnrh/p/11374541.html
Copyright © 2011-2022 走看看