• 单向链表的简单使用


    一、单向链表的概念

        单向链表是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。链表是使用指针进行构造的列表,并且是由一个个结点组装起来的,因此又称为结点列表。其中每个结点都有指针成员变量指向列表中的下一个结点,head指针指向第一个结点称为表头,而终止于最后一个指向nuLL的指针。

        结点的数据结构

     

    [objc] view plain copy
     
     
    print?
    1. typedef struct _LINK_NODE    
    2. {    
    3.     int data;    
    4.     struct _LINK_NODE* next;    
    5. }LINK_NODE;   
    typedef struct _LINK_NODE  
    {  
        int data;  
        struct _LINK_NODE* next;  
    }LINK_NODE; 


        各个结点连接在一起构成一个单向链表(示意图)

     

     

    二、单向链表的优缺点
        和普通的线性结构(如数组)相比,链表结构有以下特点:
        (1)单个结点创建非常灵活,普通的线性内存通常在创建的时候就需要设定数据的大小
        (2)结点的删除、插入非常方便,不需要像线性结构那样移动剩下的数据

        (3)结点的访问方便,可以通过循环或者递归的方法访问到任意数据,但是平均的访问效率低于线性表

     

    三、单向链表的基本操作

        1、建立一个新的链表

     

    [objc] view plain copy
     
     
    print?
    1. LINK_NODE* create_node(int value)    
    2. {    
    3.     LINK_NODE *pLinkNode = NULL;    
    4.       
    5.     pLinkNode = (LINK_NODE *)malloc(sizeof(LINK_NODE));          
    6.     pLinkNode->data = value;    
    7.     pLinkNode->next = NULL;    
    8.       
    9.     return pLinkNode;    
    10. }    
    LINK_NODE* create_node(int value)  
    {  
        LINK_NODE *pLinkNode = NULL;  
        
        pLinkNode = (LINK_NODE *)malloc(sizeof(LINK_NODE));        
        pLinkNode->data = value;  
        pLinkNode->next = NULL;  
        
        return pLinkNode;  
    }  

     

        2、增加一个结点(增加到末尾)

     

    [objc] view plain copy
     
     
    print?
    1. int _add_node(LINK_NODE** pNode, LINK_NODE* pDataNode)    
    2. {    
    3.     if(NULL == *pNode) {    
    4.         *pNode = pDataNode;    
    5.         return TRUE;    
    6.     }    
    7.         
    8.     return _add_node(&(*pNode)->next, pDataNode);    
    9. }    
    10.     
    11. int add_node(const LINK_NODE** pNode, int value)    
    12. {    
    13.     LINK_NODE *pDataNode;    
    14.       
    15.     if(NULL == *pNode) {   
    16.         return FALSE;    
    17.     }  
    18.                 
    19.     pDataNode = create_node(value);    
    20.     if(pDataNode == NULL) {  
    21.         return FALSE;  
    22.     }    
    23.       
    24.     return _add_node((LINK_NODE**)pNode, pDataNode);    
    25. }    
    int _add_node(LINK_NODE** pNode, LINK_NODE* pDataNode)  
    {  
        if(NULL == *pNode) {  
            *pNode = pDataNode;  
            return TRUE;  
        }  
          
        return _add_node(&(*pNode)->next, pDataNode);  
    }  
      
    int add_node(const LINK_NODE** pNode, int value)  
    {  
        LINK_NODE *pDataNode;  
        
        if(NULL == *pNode) { 
            return FALSE;  
        }
                  
        pDataNode = create_node(value);  
        if(pDataNode == NULL) {
            return FALSE;
        }  
        
        return _add_node((LINK_NODE**)pNode, pDataNode);  
    }  

     

        3、删除一个结点

     

    [objc] view plain copy
     
     
    print?
    1. int _delete_node(LINK_NODE** pNode, int value)    
    2. {    
    3.     LINK_NODE* pLinkNode;   
    4.        
    5.     if(NULL == (*pNode)->next) {  
    6.         return FALSE;    
    7.     }  
    8.     pLinkNode = (*pNode)->next;    
    9.     if(value == pLinkNode->data) {    
    10.         (*pNode)->next = pLinkNode->next;    
    11.         free(pLinkNode);    
    12.         return TRUE;    
    13.     } else {    
    14.         return _delete_node(&(*pNode)->next, value);    
    15.     }    
    16. }    
    17.     
    18. int delete_node(LINK_NODE** pNode, int value)    
    19. {    
    20.     LINK_NODE* pLinkNode;    
    21.       
    22.     if(NULL == pNode || NULL == *pNode) {   
    23.         return FALSE;    
    24.     }  
    25.       
    26.     if(value == (*pNode)->data) {    
    27.         pLinkNode = *pNode;    
    28.         *pNode = pLinkNode->next;    
    29.         free(pLinkNode);    
    30.         return TRUE;    
    31.     }           
    32.         
    33.     return _delete_node(pNode, value);    
    34. }    
    int _delete_node(LINK_NODE** pNode, int value)  
    {  
        LINK_NODE* pLinkNode; 
         
        if(NULL == (*pNode)->next) {
            return FALSE;  
        }
        pLinkNode = (*pNode)->next;  
        if(value == pLinkNode->data) {  
            (*pNode)->next = pLinkNode->next;  
            free(pLinkNode);  
            return TRUE;  
        } else {  
            return _delete_node(&(*pNode)->next, value);  
        }  
    }  
      
    int delete_node(LINK_NODE** pNode, int value)  
    {  
        LINK_NODE* pLinkNode;  
        
        if(NULL == pNode || NULL == *pNode) { 
            return FALSE;  
        }
        
        if(value == (*pNode)->data) {  
            pLinkNode = *pNode;  
            *pNode = pLinkNode->next;  
            free(pLinkNode);  
            return TRUE;  
        }         
          
        return _delete_node(pNode, value);  
    }  

     

        4、查找结点

     

    [objc] view plain copy
     
     
    print?
    1. //查找结点,返回数据内容为value的结点地址,没有找到返回NULL  
    2. LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value)    
    3. {    
    4.     if(NULL == pLinkNode)    
    5.         return NULL;    
    6.         
    7.     if(value == pLinkNode->data)    
    8.         return (LINK_NODE*)pLinkNode;    
    9.         
    10.     return find_node(pLinkNode->next, value);    
    11. }    
    //查找结点,返回数据内容为value的结点地址,没有找到返回NULL
    LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value)  
    {  
        if(NULL == pLinkNode)  
            return NULL;  
          
        if(value == pLinkNode->data)  
            return (LINK_NODE*)pLinkNode;  
          
        return find_node(pLinkNode->next, value);  
    }  

     

        5、统计结点个数

     

    [objc] view plain copy
     
     
    print?
    1. int count_list(const LINK_NODE *pLinkNode)    
    2. {    
    3.     if(NULL == pLinkNode) {    
    4.         return 0;    
    5.     }  
    6.            
    7.     return 1 + count_list(pLinkNode->next);    
    8. }    
    int count_list(const LINK_NODE *pLinkNode)  
    {  
        if(NULL == pLinkNode) {  
            return 0;  
        }
             
        return 1 + count_list(pLinkNode->next);  
    }  

     

        6、打印整个链表

     

    [objc] view plain copy
     
     
    print?
    1. void print_list(const LINK_NODE *pLinkNode)    
    2. {    
    3.     if(pLinkNode) {    
    4.         printf("%d ", pLinkNode->data);    
    5.         print_list(pLinkNode->next);    
    6.     }    
    7. }    
    void print_list(const LINK_NODE *pLinkNode)  
    {  
        if(pLinkNode) {  
            printf("%d
    ", pLinkNode->data);  
            print_list(pLinkNode->next);  
        }  
    }  

     

        7、删除整个链表

     

    [objc] view plain copy
     
     
    print?
    1. void delete_list(LINK_NODE** pNode)    
    2. {    
    3.     LINK_NODE** pNext;    
    4.       
    5.     if(NULL == pNode || NULL == *pNode) {    
    6.         return ;    
    7.     }      
    8.     pNext = &(*pNode)->next;    
    9.     free(*pNode);    
    10.     delete_list(pNext);     
    11. }    
    void delete_list(LINK_NODE** pNode)  
    {  
        LINK_NODE** pNext;  
        
        if(NULL == pNode || NULL == *pNode) {  
            return ;  
        }    
        pNext = &(*pNode)->next;  
        free(*pNode);  
        delete_list(pNext);   
    }  
    

     

        8、链表逆转

            链表逆转就是把链表的方向反过来,头指针变成尾指针,尾指针变成头指针,实现草图如下

            a、逆转并生成新的链表(非递归方式)

     

    [objc] view plain copy
     
     
    print?
    1. //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。  
    2. LINK_NODE *reverse_new_loop(LINK_NODE *head)  
    3. {  
    4.     LINK_NODE *p1 = NULL, *p2;  
    5.       
    6.     while(head != NULL)  
    7.     {  
    8.         p2 = (LINK_NODE *) malloc(sizeof(LINK_NODE));  
    9.         if(p1 == NULL) {  
    10.             p2->next = NULL;   
    11.         } else {  
    12.             p2->next = p1;  
    13.         }  
    14.         p1 = p2;  
    15.         p2->data = head->data;  
    16.         head = head->next;  
    17.     }  
    18.       
    19.     return p1;  
    20. }  
    //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。
    LINK_NODE *reverse_new_loop(LINK_NODE *head)
    {
        LINK_NODE *p1 = NULL, *p2;
        
        while(head != NULL)
        {
            p2 = (LINK_NODE *) malloc(sizeof(LINK_NODE));
            if(p1 == NULL) {
                p2->next = NULL; 
            } else {
                p2->next = p1;
            }
            p1 = p2;
            p2->data = head->data;
            head = head->next;
        }
        
        return p1;
    }

     

            b、逆转并生成新的链表(递归方式)

     

    [objc] view plain copy
     
     
    print?
    1. //新建一条链表,新的链表是原来链表的逆转,使用递归实现。  
    2. LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre)  
    3. {  
    4.     LINK_NODE *p = head->next;  
    5.     LINK_NODE *new;  
    6.       
    7.     new = (LINK_NODE *) malloc(sizeof(LINK_NODE));  
    8.     new->next = pre;  
    9.     new->data = head->data;  
    10.       
    11.     if(p) {  
    12.         return reverse_new_recursive(p, new);  
    13.     } else {  
    14.         return new;  
    15.     }  
    16. }  
    //新建一条链表,新的链表是原来链表的逆转,使用递归实现。
    LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre)
    {
        LINK_NODE *p = head->next;
        LINK_NODE *new;
        
        new = (LINK_NODE *) malloc(sizeof(LINK_NODE));
        new->next = pre;
        new->data = head->data;
        
        if(p) {
            return reverse_new_recursive(p, new);
        } else {
            return new;
        }
    }

     

            c、原地逆转,不生成新链表(非递归方式)

     

    [objc] view plain copy
     
     
    print?
    1. //原地逆转,使用while循环实现。  
    2. LINK_NODE *reverse_local_loop(LINK_NODE *head)   
    3. {  
    4.     LINK_NODE *p;  
    5.     LINK_NODE *tmp;  
    6.       
    7.     if(NULL == head) {  
    8.         return head;  
    9.     }  
    10.       
    11.     p = head->next;  
    12.     head->next = NULL;  
    13.   
    14.     while(NULL != p) {  
    15.         tmp = p->next;  
    16.         p->next = head;  
    17.         head = p;  
    18.         p = tmp;  
    19.     }  
    20.   
    21.     return head;  
    22. }  
    //原地逆转,使用while循环实现。
    LINK_NODE *reverse_local_loop(LINK_NODE *head) 
    {
        LINK_NODE *p;
        LINK_NODE *tmp;
        
        if(NULL == head) {
            return head;
        }
        
        p = head->next;
        head->next = NULL;
    
        while(NULL != p) {
            tmp = p->next;
            p->next = head;
            head = p;
            p = tmp;
        }
    
        return head;
    }
    

     

            d、原地逆转,不生成新链表(递归方式)

     

    [objc] view plain copy
     
     
    print?
    1. //原地逆转,使用递归实现。  
    2. LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre)   
    3. {  
    4.     LINK_NODE *p = head->next;  
    5.   
    6.     head->next = pre;  
    7.     if(p) {  
    8.         return reverse_local_recursive(p, head);  
    9.     } else {  
    10.         return head;  
    11.     }  
    12. }  
    //原地逆转,使用递归实现。
    LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre) 
    {
        LINK_NODE *p = head->next;
    
        head->next = pre;
        if(p) {
            return reverse_local_recursive(p, head);
        } else {
            return head;
        }
    }

     

        9、链表排序
            a、选择排序
                选择排序的基本思想就是反复从还未排好序的那些节点中,选出键值最小的节点, 依次重新组合成一个链表。可以通过以下三个步骤实现
                (1)先在原链表中找最小的,找到一个后就把它放到另一个空的链表中
                (2)空链表中存放第一个进来的节点,并且让它在原链表中分离出来

                (3)继续在原链表中找下一个最小的,找到后把它放入有序链表的尾指针的next,然后它变成其尾指针

     

    [objc] view plain copy
     
     
    print?
    1. //选择排序,从小到大。  
    2. LINK_NODE *SelectSort(LINK_NODE *head)  
    3. {  
    4.     LINK_NODE *first;     /*排列后有序链的表头指针*/  
    5.     LINK_NODE *tail;      /*排列后有序链的表尾指针*/  
    6.     LINK_NODE *premin;    /*保留键值更小的节点的前驱节点的指针*/  
    7.     LINK_NODE *min;       /*存储最小节点*/  
    8.     LINK_NODE *p;         /*当前比较的节点*/  
    9.   
    10.     first = NULL;  
    11.     while (head != NULL)   
    12.     {  
    13.           
    14.         //在剩余的原链表中找出最小值  
    15.         for (p = head, min = head; p->next != NULL; p = p->next) {    
    16.             if (p->next->data < min->data) {  
    17.                 premin = p;   
    18.                 min = p->next;   
    19.             }  
    20.         }  
    21.   
    22.         //将找出来最小值放到新的链表  
    23.         if (first == NULL) {  
    24.             first = min;   
    25.             tail = min;  
    26.         } else {  
    27.             tail->next = min;   
    28.             tail = min;  
    29.         }   
    30.   
    31.         //将找出来的最小值从原来的链表中脱离  
    32.         if (min == head) {  
    33.             head = head->next;  
    34.         } else {  
    35.             premin->next = min->next;  
    36.         }   
    37.     }  
    38.   
    39.     if (first != NULL) {  
    40.         tail->next = NULL;  
    41.     }  
    42.       
    43.     head = first;  
    44.     return head;  
    45. }  
    //选择排序,从小到大。
    LINK_NODE *SelectSort(LINK_NODE *head)
    {
        LINK_NODE *first;     /*排列后有序链的表头指针*/
        LINK_NODE *tail;      /*排列后有序链的表尾指针*/
        LINK_NODE *premin;    /*保留键值更小的节点的前驱节点的指针*/
        LINK_NODE *min;       /*存储最小节点*/
        LINK_NODE *p;         /*当前比较的节点*/
    
        first = NULL;
        while (head != NULL) 
        {
            
            //在剩余的原链表中找出最小值
            for (p = head, min = head; p->next != NULL; p = p->next) {  
                if (p->next->data < min->data) {
                    premin = p; 
                    min = p->next; 
                }
            }
    
            //将找出来最小值放到新的链表
            if (first == NULL) {
                first = min; 
                tail = min;
            } else {
                tail->next = min; 
                tail = min;
            } 
    
            //将找出来的最小值从原来的链表中脱离
            if (min == head) {
                head = head->next;
            } else {
                premin->next = min->next;
            } 
        }
    
        if (first != NULL) {
            tail->next = NULL;
        }
        
        head = first;
        return head;
    }
    

     

            b、插入排序
                直接插入排序的基本思想就是假设链表的前面n-1个节点是已经按键值排好序的,对于节点n在这个序列中找插入位置,使得n插入后新序列仍然有序。按照这种思想,依次对链表从头到尾执行一遍,就可以使无序链表变为有序链表。可以通过以下两个步骤实现
                (1)先在原链表中以第一个节点为一个有序链表,其余节点为待定节点

                (2)从原链表中依次取结点,插入到有序链表的相应位置,使得有序链表仍然有序,直至原链表的结点全部取完,排序结束。

     

    [objc] view plain copy
     
     
    print?
    1. //插入排序,从小到大。         
    2. LINK_NODE *InsertSort(LINK_NODE *head)  
    3. {  
    4.     LINK_NODE *first; /*为原链表剩下用于直接插入排序的节点头指针*/  
    5.     LINK_NODE *t;     /*临时指针变量:插入节点*/  
    6.     LINK_NODE *p;     /*临时指针变量*/  
    7.     LINK_NODE *q;     /*临时指针变量*/  
    8.   
    9.     first = head->next;   
    10.     head->next = NULL;   
    11.   
    12.     while (first != NULL)  
    13.     {  
    14.         //找到要插入的位置,p是q的前驱。  
    15.         for (t = first, q = head; ((q != NULL) && (q->data < t->data)); p = q, q = q->next);  
    16.   
    17.         //无序链表中的节点离开,以便它插入到有序链表中。  
    18.         first = first->next;  
    19.           
    20.         if (q == head) {  
    21.             head = t;  //插在第一个节点之前  
    22.         } else {  
    23.             p->next = t;    
    24.         }  
    25.         t->next = q;  
    26.     }  
    27.       
    28.     return head;  
    29. }        
    //插入排序,从小到大。       
    LINK_NODE *InsertSort(LINK_NODE *head)
    {
        LINK_NODE *first; /*为原链表剩下用于直接插入排序的节点头指针*/
        LINK_NODE *t;     /*临时指针变量:插入节点*/
        LINK_NODE *p;     /*临时指针变量*/
        LINK_NODE *q;     /*临时指针变量*/
    
        first = head->next; 
        head->next = NULL; 
    
        while (first != NULL)
        {
            //找到要插入的位置,p是q的前驱。
            for (t = first, q = head; ((q != NULL) && (q->data < t->data)); p = q, q = q->next);
    
            //无序链表中的节点离开,以便它插入到有序链表中。
            first = first->next;
            
            if (q == head) {
                head = t;  //插在第一个节点之前
            } else {
                p->next = t;  
            }
            t->next = q;
        }
        
        return head;
    }      

     

            c、冒泡排序

                冒泡排序的基本思想就是对当前还未排好序的范围内的全部节点,自上而下对相邻的两个节点依次进行比较和调整,让键值较大的节点往下沉,键值较小的往上冒。即:每当两相邻的节点比较后发现它们的排序与排序要求相反时,就将它们互换。

     

    [objc] view plain copy
     
     
    print?
    1. //冒泡排序,从小到大。  
    2. LINK_NODE *BubbleSort(LINK_NODE *head)  
    3. {  
    4.     LINK_NODE *endpt; /*控制循环比较*/  
    5.     LINK_NODE *p;     /*临时指针变量*/  
    6.     LINK_NODE *p1;  
    7.     LINK_NODE *p2;  
    8.   
    9.     p1 = (LINK_NODE *)malloc(sizeof(LINK_NODE));  
    10.     p1->next = head;  
    11.     head = p1;  
    12.   
    13.     for (endpt = NULL; endpt != head; endpt = p) {  
    14.         for (p = p1 = head; p1->next->next != endpt; p1 = p1->next) {  
    15.             if (p1->next->data > p1->next->next->data) {  
    16.                 p2 = p1->next->next;   
    17.                 p1->next->next = p2->next;   
    18.                 p2->next = p1->next;   
    19.                 p1->next = p2;   
    20.                 p = p1->next->next;   
    21.             }  
    22.         }  
    23.     }  
    24.   
    25.     p1 = head;   
    26.     head = head->next;  
    27.     free(p1);   
    28.     p1 = NULL;   
    29.   
    30.     return head;  
    31. }  
    //冒泡排序,从小到大。
    LINK_NODE *BubbleSort(LINK_NODE *head)
    {
        LINK_NODE *endpt; /*控制循环比较*/
        LINK_NODE *p;     /*临时指针变量*/
        LINK_NODE *p1;
        LINK_NODE *p2;
    
        p1 = (LINK_NODE *)malloc(sizeof(LINK_NODE));
        p1->next = head;
        head = p1;
    
        for (endpt = NULL; endpt != head; endpt = p) {
            for (p = p1 = head; p1->next->next != endpt; p1 = p1->next) {
                if (p1->next->data > p1->next->next->data) {
                    p2 = p1->next->next; 
                    p1->next->next = p2->next; 
                    p2->next = p1->next; 
                    p1->next = p2; 
                    p = p1->next->next; 
                }
            }
        }
    
        p1 = head; 
        head = head->next;
        free(p1); 
        p1 = NULL; 
    
        return head;
    }
    

     

    四、单向链表运用示例

        将链表的基本操作统一放在一个文件single_linkedlist.c里面,然后在single_linkedlist.h文件里面声明,这样调用起来比较方便。下面贴出各个文件的代码,方面下次快速使用。

        single_linkedlist.c文件代码

     

    [objc] view plain copy
     
     
    print?
    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3.   
    4. #include "single_linkedlist.h"  
    5.   
    6. //创建一个结点  
    7. LINK_NODE* create_node(int value)    
    8. {    
    9.     LINK_NODE *pLinkNode = NULL;    
    10.       
    11.     pLinkNode = (LINK_NODE *)malloc(sizeof(LINK_NODE));          
    12.     pLinkNode->data = value;    
    13.     pLinkNode->next = NULL;    
    14.       
    15.     return pLinkNode;    
    16. }    
    17.   
    18. //使用递归的方法,在链表的末尾加上一个新的结点  
    19. int _add_node(LINK_NODE** pNode, LINK_NODE* pDataNode)    
    20. {    
    21.     if(NULL == *pNode) {    
    22.         *pNode = pDataNode;    
    23.         return TRUE;    
    24.     }    
    25.         
    26.     return _add_node(&(*pNode)->next, pDataNode);    
    27. }    
    28.     
    29. int add_node(const LINK_NODE** pNode, int value)    
    30. {    
    31.     LINK_NODE *pDataNode;    
    32.       
    33.     if(NULL == *pNode) {   
    34.         return FALSE;    
    35.     }  
    36.                 
    37.     pDataNode = create_node(value);    
    38.     if(pDataNode == NULL) {  
    39.         return FALSE;  
    40.     }    
    41.       
    42.     return _add_node((LINK_NODE**)pNode, pDataNode);    
    43. }    
    44.   
    45. //使用递归的方法,删除数据内容为value的结点  
    46. int _delete_node(LINK_NODE** pNode, int value)    
    47. {    
    48.     LINK_NODE* pLinkNode;   
    49.        
    50.     if(NULL == (*pNode)->next) {  
    51.         return FALSE;    
    52.     }  
    53.     pLinkNode = (*pNode)->next;    
    54.     if(value == pLinkNode->data) {    
    55.         (*pNode)->next = pLinkNode->next;    
    56.         free(pLinkNode);    
    57.         return TRUE;    
    58.     } else {    
    59.         return _delete_node(&(*pNode)->next, value);    
    60.     }    
    61. }    
    62.     
    63. int delete_node(LINK_NODE** pNode, int value)    
    64. {    
    65.     LINK_NODE* pLinkNode;    
    66.       
    67.     if(NULL == pNode || NULL == *pNode) {   
    68.         return FALSE;    
    69.     }  
    70.       
    71.     if(value == (*pNode)->data) {    
    72.         pLinkNode = *pNode;    
    73.         *pNode = pLinkNode->next;    
    74.         free(pLinkNode);    
    75.         return TRUE;    
    76.     }           
    77.         
    78.     return _delete_node(pNode, value);    
    79. }    
    80.   
    81. //查找结点,返回数据内容为value的结点地址,没有找到返回NULL.  
    82. LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value)    
    83. {    
    84.     if(NULL == pLinkNode)    
    85.         return NULL;    
    86.         
    87.     if(value == pLinkNode->data)    
    88.         return (LINK_NODE*)pLinkNode;    
    89.         
    90.     return find_node(pLinkNode->next, value);    
    91. }    
    92.   
    93. //把从pLinkNode结点开始到链表结束的结点个数统计出来  
    94. //一般pLinkNode链表头  
    95. int count_list(const LINK_NODE *pLinkNode)    
    96. {    
    97.     if(NULL == pLinkNode) {    
    98.         return 0;    
    99.     }  
    100.            
    101.     return 1 + count_list(pLinkNode->next);    
    102. }    
    103.       
    104. //把从pLinkNode结点开始到链表结束的数据全部打印出来  
    105. //一般pLinkNode为链表头  
    106. void print_list(const LINK_NODE *pLinkNode)    
    107. {    
    108.     if(pLinkNode) {    
    109.         printf("%d ", pLinkNode->data);    
    110.         print_list(pLinkNode->next);    
    111.     }    
    112. }    
    113.   
    114. //删除整个链表,pNode为链表头。  
    115. void delete_list(LINK_NODE** pNode)    
    116. {    
    117.     LINK_NODE** pNext;    
    118.       
    119.     if(NULL == pNode || NULL == *pNode) {    
    120.         return ;    
    121.     }      
    122.     pNext = &(*pNode)->next;    
    123.     free(*pNode);    
    124.     delete_list(pNext);     
    125. }    
    126.   
    127. //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。  
    128. LINK_NODE *reverse_new_loop(LINK_NODE *head)  
    129. {  
    130.     LINK_NODE *p1 = NULL, *p2;  
    131.       
    132.     while(head != NULL)  
    133.     {  
    134.         p2 = (LINK_NODE *) malloc(sizeof(LINK_NODE));  
    135.         if(p1 == NULL) {  
    136.             p2->next = NULL;   
    137.         } else {  
    138.             p2->next = p1;  
    139.         }  
    140.         p1 = p2;  
    141.         p2->data = head->data;  
    142.         head = head->next;  
    143.     }  
    144.       
    145.     return p1;  
    146. }  
    147.   
    148. //新建一条链表,新的链表是原来链表的逆转,使用递归实现。  
    149. LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre)  
    150. {  
    151.     LINK_NODE *p = head->next;  
    152.     LINK_NODE *new;  
    153.       
    154.     new = (LINK_NODE *) malloc(sizeof(LINK_NODE));  
    155.     new->next = pre;  
    156.     new->data = head->data;  
    157.       
    158.     if(p) {  
    159.         return reverse_new_recursive(p, new);  
    160.     } else {  
    161.         return new;  
    162.     }  
    163. }  
    164.   
    165. //原地逆转,使用while循环实现。  
    166. LINK_NODE *reverse_local_loop(LINK_NODE *head)   
    167. {  
    168.     LINK_NODE *p;  
    169.     LINK_NODE *tmp;  
    170.       
    171.     if(NULL == head) {  
    172.         return head;  
    173.     }  
    174.       
    175.     p = head->next;  
    176.     head->next = NULL;  
    177.   
    178.     while(NULL != p) {  
    179.         tmp = p->next;  
    180.         p->next = head;  
    181.         head = p;  
    182.         p = tmp;  
    183.     }  
    184.   
    185.     return head;  
    186. }  
    187.   
    188. //原地逆转,使用递归实现。  
    189. LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre)   
    190. {  
    191.     LINK_NODE *p = head->next;  
    192.   
    193.     head->next = pre;  
    194.     if(p) {  
    195.         return reverse_local_recursive(p, head);  
    196.     } else {  
    197.         return head;  
    198.     }  
    199. }  
    200.   
    201. //选择排序,从小到大。  
    202. LINK_NODE *SelectSort(LINK_NODE *head)  
    203. {  
    204.     LINK_NODE *first;     /*排列后有序链的表头指针*/  
    205.     LINK_NODE *tail;      /*排列后有序链的表尾指针*/  
    206.     LINK_NODE *premin;    /*保留键值更小的节点的前驱节点的指针*/  
    207.     LINK_NODE *min;       /*存储最小节点*/  
    208.     LINK_NODE *p;         /*当前比较的节点*/  
    209.   
    210.     first = NULL;  
    211.     while (head != NULL)   
    212.     {  
    213.           
    214.         //在剩余的原链表中找出最小值  
    215.         for (p = head, min = head; p->next != NULL; p = p->next) {    
    216.             if (p->next->data < min->data) {  
    217.                 premin = p;   
    218.                 min = p->next;   
    219.             }  
    220.         }  
    221.   
    222.         //将找出来最小值放到新的链表  
    223.         if (first == NULL) {  
    224.             first = min;   
    225.             tail = min;  
    226.         } else {  
    227.             tail->next = min;   
    228.             tail = min;  
    229.         }   
    230.   
    231.         //将找出来的最小值从原来的链表中脱离  
    232.         if (min == head) {  
    233.             head = head->next;  
    234.         } else {  
    235.             premin->next = min->next;  
    236.         }   
    237.     }  
    238.   
    239.     if (first != NULL) {  
    240.         tail->next = NULL;  
    241.     }  
    242.       
    243.     head = first;  
    244.     return head;  
    245. }  
    246.   
    247. //插入排序,从小到大。         
    248. LINK_NODE *InsertSort(LINK_NODE *head)  
    249. {  
    250.     LINK_NODE *first; /*为原链表剩下用于直接插入排序的节点头指针*/  
    251.     LINK_NODE *t;     /*临时指针变量:插入节点*/  
    252.     LINK_NODE *p;     /*临时指针变量*/  
    253.     LINK_NODE *q;     /*临时指针变量*/  
    254.   
    255.     first = head->next;   
    256.     head->next = NULL;   
    257.   
    258.     while (first != NULL)  
    259.     {  
    260.         //找到要插入的位置,p是q的前驱。  
    261.         for (t = first, q = head; ((q != NULL) && (q->data < t->data)); p = q, q = q->next);  
    262.   
    263.         //无序链表中的节点离开,以便它插入到有序链表中。  
    264.         first = first->next;  
    265.           
    266.         if (q == head) {  
    267.             head = t;  //插在第一个节点之前  
    268.         } else {  
    269.             p->next = t;    
    270.         }  
    271.         t->next = q;  
    272.     }  
    273.       
    274.     return head;  
    275. }        
    276.   
    277. //冒泡排序,从小到大。  
    278. LINK_NODE *BubbleSort(LINK_NODE *head)  
    279. {  
    280.     LINK_NODE *endpt; /*控制循环比较*/  
    281.     LINK_NODE *p;     /*临时指针变量*/  
    282.     LINK_NODE *p1;  
    283.     LINK_NODE *p2;  
    284.   
    285.     p1 = (LINK_NODE *)malloc(sizeof(LINK_NODE));  
    286.     p1->next = head;  
    287.     head = p1;  
    288.   
    289.     for (endpt = NULL; endpt != head; endpt = p) {  
    290.         for (p = p1 = head; p1->next->next != endpt; p1 = p1->next) {  
    291.             if (p1->next->data > p1->next->next->data) {  
    292.                 p2 = p1->next->next;   
    293.                 p1->next->next = p2->next;   
    294.                 p2->next = p1->next;   
    295.                 p1->next = p2;   
    296.                 p = p1->next->next;   
    297.             }  
    298.         }  
    299.     }  
    300.   
    301.     p1 = head;   
    302.     head = head->next;  
    303.     free(p1);   
    304.     p1 = NULL;   
    305.   
    306.     return head;  
    307. }  
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "single_linkedlist.h"
    
    //创建一个结点
    LINK_NODE* create_node(int value)  
    {  
        LINK_NODE *pLinkNode = NULL;  
        
        pLinkNode = (LINK_NODE *)malloc(sizeof(LINK_NODE));        
        pLinkNode->data = value;  
        pLinkNode->next = NULL;  
        
        return pLinkNode;  
    }  
    
    //使用递归的方法,在链表的末尾加上一个新的结点
    int _add_node(LINK_NODE** pNode, LINK_NODE* pDataNode)  
    {  
        if(NULL == *pNode) {  
            *pNode = pDataNode;  
            return TRUE;  
        }  
          
        return _add_node(&(*pNode)->next, pDataNode);  
    }  
      
    int add_node(const LINK_NODE** pNode, int value)  
    {  
        LINK_NODE *pDataNode;  
        
        if(NULL == *pNode) { 
            return FALSE;  
        }
                  
        pDataNode = create_node(value);  
        if(pDataNode == NULL) {
            return FALSE;
        }  
        
        return _add_node((LINK_NODE**)pNode, pDataNode);  
    }  
    
    //使用递归的方法,删除数据内容为value的结点
    int _delete_node(LINK_NODE** pNode, int value)  
    {  
        LINK_NODE* pLinkNode; 
         
        if(NULL == (*pNode)->next) {
            return FALSE;  
        }
        pLinkNode = (*pNode)->next;  
        if(value == pLinkNode->data) {  
            (*pNode)->next = pLinkNode->next;  
            free(pLinkNode);  
            return TRUE;  
        } else {  
            return _delete_node(&(*pNode)->next, value);  
        }  
    }  
      
    int delete_node(LINK_NODE** pNode, int value)  
    {  
        LINK_NODE* pLinkNode;  
        
        if(NULL == pNode || NULL == *pNode) { 
            return FALSE;  
        }
        
        if(value == (*pNode)->data) {  
            pLinkNode = *pNode;  
            *pNode = pLinkNode->next;  
            free(pLinkNode);  
            return TRUE;  
        }         
          
        return _delete_node(pNode, value);  
    }  
    
    //查找结点,返回数据内容为value的结点地址,没有找到返回NULL.
    LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value)  
    {  
        if(NULL == pLinkNode)  
            return NULL;  
          
        if(value == pLinkNode->data)  
            return (LINK_NODE*)pLinkNode;  
          
        return find_node(pLinkNode->next, value);  
    }  
    
    //把从pLinkNode结点开始到链表结束的结点个数统计出来
    //一般pLinkNode链表头
    int count_list(const LINK_NODE *pLinkNode)  
    {  
        if(NULL == pLinkNode) {  
            return 0;  
        }
             
        return 1 + count_list(pLinkNode->next);  
    }  
        
    //把从pLinkNode结点开始到链表结束的数据全部打印出来
    //一般pLinkNode为链表头
    void print_list(const LINK_NODE *pLinkNode)  
    {  
        if(pLinkNode) {  
            printf("%d
    ", pLinkNode->data);  
            print_list(pLinkNode->next);  
        }  
    }  
    
    //删除整个链表,pNode为链表头。
    void delete_list(LINK_NODE** pNode)  
    {  
        LINK_NODE** pNext;  
        
        if(NULL == pNode || NULL == *pNode) {  
            return ;  
        }    
        pNext = &(*pNode)->next;  
        free(*pNode);  
        delete_list(pNext);   
    }  
    
    //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。
    LINK_NODE *reverse_new_loop(LINK_NODE *head)
    {
        LINK_NODE *p1 = NULL, *p2;
        
        while(head != NULL)
        {
            p2 = (LINK_NODE *) malloc(sizeof(LINK_NODE));
            if(p1 == NULL) {
                p2->next = NULL; 
            } else {
                p2->next = p1;
            }
            p1 = p2;
            p2->data = head->data;
            head = head->next;
        }
        
        return p1;
    }
    
    //新建一条链表,新的链表是原来链表的逆转,使用递归实现。
    LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre)
    {
        LINK_NODE *p = head->next;
        LINK_NODE *new;
        
        new = (LINK_NODE *) malloc(sizeof(LINK_NODE));
        new->next = pre;
        new->data = head->data;
        
        if(p) {
            return reverse_new_recursive(p, new);
        } else {
            return new;
        }
    }
    
    //原地逆转,使用while循环实现。
    LINK_NODE *reverse_local_loop(LINK_NODE *head) 
    {
        LINK_NODE *p;
        LINK_NODE *tmp;
        
        if(NULL == head) {
            return head;
        }
        
        p = head->next;
        head->next = NULL;
    
        while(NULL != p) {
            tmp = p->next;
            p->next = head;
            head = p;
            p = tmp;
        }
    
        return head;
    }
    
    //原地逆转,使用递归实现。
    LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre) 
    {
        LINK_NODE *p = head->next;
    
        head->next = pre;
        if(p) {
            return reverse_local_recursive(p, head);
        } else {
            return head;
        }
    }
    
    //选择排序,从小到大。
    LINK_NODE *SelectSort(LINK_NODE *head)
    {
        LINK_NODE *first;     /*排列后有序链的表头指针*/
        LINK_NODE *tail;      /*排列后有序链的表尾指针*/
        LINK_NODE *premin;    /*保留键值更小的节点的前驱节点的指针*/
        LINK_NODE *min;       /*存储最小节点*/
        LINK_NODE *p;         /*当前比较的节点*/
    
        first = NULL;
        while (head != NULL) 
        {
            
            //在剩余的原链表中找出最小值
            for (p = head, min = head; p->next != NULL; p = p->next) {  
                if (p->next->data < min->data) {
                    premin = p; 
                    min = p->next; 
                }
            }
    
            //将找出来最小值放到新的链表
            if (first == NULL) {
                first = min; 
                tail = min;
            } else {
                tail->next = min; 
                tail = min;
            } 
    
            //将找出来的最小值从原来的链表中脱离
            if (min == head) {
                head = head->next;
            } else {
                premin->next = min->next;
            } 
        }
    
        if (first != NULL) {
            tail->next = NULL;
        }
        
        head = first;
        return head;
    }
    
    //插入排序,从小到大。       
    LINK_NODE *InsertSort(LINK_NODE *head)
    {
        LINK_NODE *first; /*为原链表剩下用于直接插入排序的节点头指针*/
        LINK_NODE *t;     /*临时指针变量:插入节点*/
        LINK_NODE *p;     /*临时指针变量*/
        LINK_NODE *q;     /*临时指针变量*/
    
        first = head->next; 
        head->next = NULL; 
    
        while (first != NULL)
        {
            //找到要插入的位置,p是q的前驱。
            for (t = first, q = head; ((q != NULL) && (q->data < t->data)); p = q, q = q->next);
    
            //无序链表中的节点离开,以便它插入到有序链表中。
            first = first->next;
            
            if (q == head) {
                head = t;  //插在第一个节点之前
            } else {
                p->next = t;  
            }
            t->next = q;
        }
        
        return head;
    }      
    
    //冒泡排序,从小到大。
    LINK_NODE *BubbleSort(LINK_NODE *head)
    {
        LINK_NODE *endpt; /*控制循环比较*/
        LINK_NODE *p;     /*临时指针变量*/
        LINK_NODE *p1;
        LINK_NODE *p2;
    
        p1 = (LINK_NODE *)malloc(sizeof(LINK_NODE));
        p1->next = head;
        head = p1;
    
        for (endpt = NULL; endpt != head; endpt = p) {
            for (p = p1 = head; p1->next->next != endpt; p1 = p1->next) {
                if (p1->next->data > p1->next->next->data) {
                    p2 = p1->next->next; 
                    p1->next->next = p2->next; 
                    p2->next = p1->next; 
                    p1->next = p2; 
                    p = p1->next->next; 
                }
            }
        }
    
        p1 = head; 
        head = head->next;
        free(p1); 
        p1 = NULL; 
    
        return head;
    }


        single_linkedlist.h文件代码

     

     

    [objc] view plain copy
     
     
    print?
    1. #ifndef _SINGLE_LINKEDLIST_H_  
    2. #define _SINGLE_LINKEDLIST_H_  
    3.   
    4. #define TRUE       1  
    5. #define FALSE      0  
    6.   
    7. //定义结点数据结构  
    8. typedef struct _LINK_NODE    
    9. {    
    10.     int data;    
    11.     struct _LINK_NODE* next;    
    12. }LINK_NODE;   
    13.   
    14.   
    15. //创建一个结点  
    16. LINK_NODE* create_node(int value);  
    17.   
    18. //删除整个链表,pNode为链表头。  
    19. void delete_list(LINK_NODE** pNode);   
    20.   
    21. //使用递归的方法,在链表的末尾加上一个新的结点  
    22. int add_node(const LINK_NODE** pNode, int value);  
    23.   
    24. //使用递归的方法,删除数据内容为value的结点  
    25. int delete_node(LINK_NODE** pNode, int value);  
    26.   
    27. //查找结点,返回数据内容为value的结点地址,没有找到返回NULL  
    28. LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value);  
    29.   
    30. //把从pLinkNode结点开始到链表结束的结点个数统计出来  
    31. //一般pLinkNode链表头  
    32. int count_list(const LINK_NODE *pLinkNode);  
    33.   
    34. //把从pLinkNode结点开始到链表结束的数据全部打印出来  
    35. //一般pLinkNode为链表头  
    36. void print_list(const LINK_NODE *pLinkNode);   
    37.   
    38. //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。  
    39. LINK_NODE *reverse_new_loop(LINK_NODE *head);  
    40.   
    41. //新建一条链表,新的链表是原来链表的逆转,使用递归实现。  
    42. LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre);  
    43.   
    44. //原地逆转,使用while循环实现。  
    45. LINK_NODE *reverse_local_loop(LINK_NODE *head);  
    46.   
    47. //原地逆转,使用递归实现。  
    48. LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre);  
    49.   
    50. //选择排序,从小到大。  
    51. LINK_NODE *SelectSort(LINK_NODE *head);  
    52.   
    53. //插入排序,从小到大。         
    54. LINK_NODE *InsertSort(LINK_NODE *head);  
    55.   
    56. //冒泡排序,从小到大。  
    57. LINK_NODE *BubbleSort(LINK_NODE *head);  
    58.   
    59. #endif  
    #ifndef _SINGLE_LINKEDLIST_H_
    #define _SINGLE_LINKEDLIST_H_
    
    #define TRUE       1
    #define FALSE      0
    
    //定义结点数据结构
    typedef struct _LINK_NODE  
    {  
        int data;  
        struct _LINK_NODE* next;  
    }LINK_NODE; 
    
    
    //创建一个结点
    LINK_NODE* create_node(int value);
    
    //删除整个链表,pNode为链表头。
    void delete_list(LINK_NODE** pNode); 
    
    //使用递归的方法,在链表的末尾加上一个新的结点
    int add_node(const LINK_NODE** pNode, int value);
    
    //使用递归的方法,删除数据内容为value的结点
    int delete_node(LINK_NODE** pNode, int value);
    
    //查找结点,返回数据内容为value的结点地址,没有找到返回NULL
    LINK_NODE* find_node(const LINK_NODE* pLinkNode, int value);
    
    //把从pLinkNode结点开始到链表结束的结点个数统计出来
    //一般pLinkNode链表头
    int count_list(const LINK_NODE *pLinkNode);
    
    //把从pLinkNode结点开始到链表结束的数据全部打印出来
    //一般pLinkNode为链表头
    void print_list(const LINK_NODE *pLinkNode); 
    
    //新建一条链表,新的链表是原来链表的逆转,使用while循环实现。
    LINK_NODE *reverse_new_loop(LINK_NODE *head);
    
    //新建一条链表,新的链表是原来链表的逆转,使用递归实现。
    LINK_NODE *reverse_new_recursive(LINK_NODE *head, LINK_NODE *pre);
    
    //原地逆转,使用while循环实现。
    LINK_NODE *reverse_local_loop(LINK_NODE *head);
    
    //原地逆转,使用递归实现。
    LINK_NODE *reverse_local_recursive(LINK_NODE *head, LINK_NODE *pre);
    
    //选择排序,从小到大。
    LINK_NODE *SelectSort(LINK_NODE *head);
    
    //插入排序,从小到大。       
    LINK_NODE *InsertSort(LINK_NODE *head);
    
    //冒泡排序,从小到大。
    LINK_NODE *BubbleSort(LINK_NODE *head);
    
    #endif
    
    


        main.c文件代码

     

     

    [objc] view plain copy
     
     
    print?
    1. #include <stdio.h>  
    2. #include <stdlib.h>  
    3.   
    4. #include "single_linkedlist.h"  
    5.   
    6. int main(int argc, charchar **argv)  
    7. {  
    8.     LINK_NODE *head;  
    9.     LINK_NODE *reverse1, *reverse2;  
    10.       
    11.     head = create_node(1);      
    12.     add_node((const LINK_NODE **)&head, 5);  
    13.     add_node((const LINK_NODE **)&head, 2);  
    14.     add_node((const LINK_NODE **)&head, 4);  
    15.     add_node((const LINK_NODE **)&head, 3);    
    16.       
    17.     printf("=======原始链表head ");    
    18.     print_list(head);  
    19.       
    20.       
    21.     //逆转生成一个新的链表,循环实现  
    22.     reverse1 = reverse_new_loop(head);  
    23.     printf("=======head逆转成的链表reverse1 ");  
    24.     print_list(reverse1);      
    25.       
    26.     //逆转生成一个新的链表,递归实现  
    27.     reverse2 = reverse_new_recursive(head, NULL);  
    28.     printf("=======head逆转成的链表reverse2 ");  
    29.     print_list(reverse2);  
    30.   
    31.     //本地逆转,循环实现          
    32.     reverse1 = reverse_local_loop(reverse1);  
    33.     printf("=======reverse1本地逆转成的链表reverse1 ");  
    34.     print_list(reverse1);      
    35.       
    36.     //本地逆转,递归实现  
    37.     reverse2 = reverse_local_loop(reverse2);  
    38.     printf("=======reverse2本地逆转成的链表reverse2 ");  
    39.     print_list(reverse2);  
    40.       
    41.     //选择排序  
    42.     head = SelectSort(head);  
    43.     printf("=======head选择排序后的链表 ");  
    44.     print_list(head);      
    45.       
    46.     //插入排序  
    47.     reverse1 = InsertSort(reverse1);  
    48.     printf("=======reverse1插入排序后的链表 ");  
    49.     print_list(reverse1);  
    50.   
    51.     //冒泡排序  
    52.     reverse2 = BubbleSort(reverse2);    
    53.     printf("=======reverse2冒泡排序后的链表 ");  
    54.     print_list(reverse2);  
    55.   
    56.     delete_list(&head);  
    57.     delete_list(&reverse1);  
    58.     delete_list(&reverse2);  
    59.                    
    60.     return 0;  
    61. }  
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "single_linkedlist.h"
    
    int main(int argc, char **argv)
    {
        LINK_NODE *head;
        LINK_NODE *reverse1, *reverse2;
        
        head = create_node(1);    
        add_node((const LINK_NODE **)&head, 5);
        add_node((const LINK_NODE **)&head, 2);
        add_node((const LINK_NODE **)&head, 4);
        add_node((const LINK_NODE **)&head, 3);  
        
        printf("=======原始链表head
    ");  
        print_list(head);
        
        
        //逆转生成一个新的链表,循环实现
        reverse1 = reverse_new_loop(head);
        printf("=======head逆转成的链表reverse1
    ");
        print_list(reverse1);    
        
        //逆转生成一个新的链表,递归实现
        reverse2 = reverse_new_recursive(head, NULL);
        printf("=======head逆转成的链表reverse2
    ");
        print_list(reverse2);
    
        //本地逆转,循环实现        
        reverse1 = reverse_local_loop(reverse1);
        printf("=======reverse1本地逆转成的链表reverse1
    ");
        print_list(reverse1);    
        
        //本地逆转,递归实现
        reverse2 = reverse_local_loop(reverse2);
        printf("=======reverse2本地逆转成的链表reverse2
    ");
        print_list(reverse2);
        
        //选择排序
        head = SelectSort(head);
        printf("=======head选择排序后的链表
    ");
        print_list(head);    
        
        //插入排序
        reverse1 = InsertSort(reverse1);
        printf("=======reverse1插入排序后的链表
    ");
        print_list(reverse1);
    
        //冒泡排序
        reverse2 = BubbleSort(reverse2);  
        printf("=======reverse2冒泡排序后的链表
    ");
        print_list(reverse2);
    
        delete_list(&head);
        delete_list(&reverse1);
        delete_list(&reverse2);
                     
        return 0;
    }


        Makefile文件代码

     

     

    [objc] view plain copy
     
     
    print?
      1. CC       = gcc  
      2. WORKDIR  =   
      3. INCLUDES =   
      4. LIBS     =  
      5. LINKS    =  
      6. TARGET   = main  
      7.   
      8. src=$(wildcard *.c ./callback/*.c)  
      9. C_OBJS=$(patsubst %.c, %.o,$(src))  
      10. #C_OBJS=$(dir:%.c=%.o)  
      11.   
      12. compile:$(TARGET)  
      13.       
      14. $(C_OBJS):%.o:%.c  
      15.     $(CC) $(CFLAGS) $(INCLUDES) -o $*.o -c $*.c  
      16.       
      17. $(TARGET):$(C_OBJS)  
      18.     $(CC) -o $(TARGET) $^ $(LIBS) $(LINKS)   
      19.   
      20.     @echo   
      21.     @echo Project has been successfully compiled.  
      22.     @echo  
      23.       
      24. install: $(TARGET)  
      25.     cp $(TARGET) $(INSTALL_PATH)  
      26.   
      27. uninstall:  
      28.     rm -f $(INSTALL_PATH)/$(TARGET)  
      29.   
      30. rebuild: clean compile  
      31.   
      32. clean:  
      33.     rm -rf *.o  $(TARGET) *.log *~  
  • 相关阅读:
    01 变量、基本数据类型
    02 gitlab的基本使用
    kubernetes
    02 redis高可用集群
    Redis & ELK
    01 Redis安装、配置详解、数据备份与恢复
    Jenkins
    01 git gitlab jenkins的安装
    golang mysql 客户端
    接口类
  • 原文地址:https://www.cnblogs.com/oneway1990/p/9202572.html
Copyright © 2020-2023  润新知