首页 > 其他 > 详细

单链表的函数实现

时间:2015-11-22 23:35:04      阅读:607      评论:0      收藏:0      [点我收藏+]


下面就是我实现的单链表的各个功能的函数,可能会有考虑不周的地方


#include <stdio.h>
#include <malloc.h>
#include <assert.h>

typedef int DataType;            //数据类型重命名

typedef struct _node            //定义节点结构体
{
    DataType data;            //数据
    struct _node* next;        //指向下一个节点的指针
}ListNode;



void InitList(ListNode** phead)            //初始化phead
{
    *phead = NULL;
}




ListNode* CreatNode(DataType val)   //创建一个DataType数据为val的新节点
{
    ListNode* tmp = (ListNode*)malloc(sizeof(ListNode));      //malloc开辟空间
    assert(tmp);        //判空
    tmp->data = val;
    tmp->next = NULL;
    return tmp;
}



void PushBack(ListNode** phead, DataType x)    //尾插一个新的节点
{
    if (*phead == NULL)            //空链表
    {
        *phead = CreatNode(x);
    }
    else                            //非空链表
    {
        ListNode* tail = *phead;
        while (tail->next)
        {
            tail = tail->next;
        }
        tail->next = CreatNode(x);
    }
}




void ShowList(ListNode* phead)        //打印单链表
{           
    if(NULL == phead)              //判空
    {
        printf("list is empty!\n");
    }
    ListNode* cur = phead;
    while (cur)
    {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
}




void PushHead(ListNode** head, DataType x)        //头插一个新节点
{
    //if (NULL == *head)                //空链表
    //{
    //    *head = CreatNode(x);
    //}
    //else                            //非空链表
    //{
    //    ListNode* tmp = CreatNode(x);
    //    tmp->next = *head;
    //    *head = tmp;
    //}

    ListNode* tmp = CreatNode(x);            //没有分情况,也没有什么问题
    tmp->next = *head;
    *head = tmp;
}




void PopBack(ListNode** phead)        //删除尾部节点
{
    if (NULL == *phead)                //空链表
    {
        printf("list is empty!");
        return;
    }
    else if (NULL == (*phead)->next)    //只有一个节点
    {
        free(*phead);
        *phead = NULL;                //free后置空,防止野指针出现
    }
    else                               //多个节点
    {
        ListNode* tail = *phead;
        ListNode* pre = *phead;
        while (tail->next)            //先找到尾节点
        {
            pre = tail;
            tail = tail->next;
        }
        pre->next = NULL;
        free(tail);
    }
}




void PopFront(ListNode** phead)        //删除头结点
{
    if (NULL == *phead)        //空链表
    {
        printf("list is empty!");
        return;
    }
    else                     //非空链表
    {
        ListNode* tag = *phead;
        *phead = (*phead)->next;
        free(tag);
    }
}




ListNode* Find(ListNode** phead, DataType x)      //链表中寻找data值为x的节点
{
    ListNode* cur = *phead;
    while (cur)
    {
        if (cur->data == x)
        {
            return cur;
        }
        
        cur = cur->next;
    }
    return NULL;
}




void Insert(ListNode* pos, DataType x)            //在pos位置进行插入
{
    assert(pos);
    ListNode* new_node = CreatNode(x);
    ListNode* tmp = pos->next;
    new_node->data = pos->data;//将x赋值给pos->data,将pos->data赋值给pos->data;交换顺序
    pos->data = x;
    pos->next = new_node;
    new_node->next = tmp;
}




void InsertFrontNode(ListNode* pos, DataType x)         //在pos位置的前面进行插入
{
    assert(pos);
    ListNode* tmp = CreatNode(x);
    tmp->next = pos->next;
    pos->next = tmp;
    tmp->data = pos->data;

    pos->data = x;
    
}




void Erase(ListNode** phead, ListNode* pos)        //删除pos节点
{
    assert(pos);
    if (pos == *phead)            //pos是第一个节点
    {
        *phead = (*phead)->next;
        free(pos);
    }
    else                     //pos是任意节点
    {
        ListNode* cur = *phead;
        while (cur)
        {
            if (cur->next == pos)
            {
                cur->next = pos->next;
                free(pos);
                break;
            }
            cur = cur->next;
        }
    }
}




void DelNonTailNode(ListNode* pos)     //删除非尾节点
{
    assert(pos && pos->next);
    
    ListNode* del = pos->next;//将pos->next->data赋值给pos->data,把pos->next  free,在串起来
    ListNode* tmp = pos->next->next;
    pos->data = pos->next->data;
    pos->next = tmp;
    free(del);
}




void Remove(ListNode** phead, DataType x)          //删除节点data值为x的节点
{
    ListNode* remv = Find(phead, x);
    if (remv)
    {
        Erase(phead, remv);        //调用Erase函数
    }
}




ListNode* Reverse(ListNode* phead)    //逆置翻转链表
{
    ListNode* newHead = NULL;
    ListNode* cur = phead;
    while (cur)
    {
        ListNode* tmp = cur;        //进行摘节点,再进行尾插
        cur = cur->next;

        tmp->next = newHead;
        newHead = tmp;
    }
    return newHead;
}




void PrintTailtoHead(ListNode* phead)        //递归实现从尾到头打印
{
    if (phead)
    {
        PrintTailtoHead(phead->next);
        printf("%d ", head->data);
    }
}




ListNode* FindMid(ListNode* phead)            //找链表中间节点并返回
{
    ListNode* slow = phead;                  //slow 指针
    ListNode* fast = phead;                //fast指针
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
    }
    return slow;
}




DataType Find_TheLast_Knode(ListNode* phead, int k)  //查找倒数第K个节点,遍历一次
{
    assert(phead);
    ListNode* pre = phead;                 //定义两个指针,分别指向前面和后面
    ListNode* aft = phead;
    int i = 1;
    while (aft)
    {
        if (i <= k)
        {
            aft = aft->next;
            i++;
        }
        else
        {
            aft = aft->next;
            pre = pre->next;
        }
    }                      //指针aft和pre保持距离为(k-1),则遍历完成之后,pre即为倒数第K个节点
    if ( i > k && k != 0)  //不存在倒数第0个节点
    {
        return pre->data;
    }
    else
        return -1;
}

void swap(DataType* n, DataType* m)        //交换两个数
{
    DataType tmp = *n;
    *n = *m;
    *m = tmp;
}




void BubbleSort(ListNode** head)                //链表的冒泡排序
{
    assert(head);
    //一个节点
    if (NULL == (*head)->next)
    {
        return;
    }
    else
    {
        while (1)
        {
            ListNode* cur = (*head)->next;
            ListNode* p = *head;
            int exchange = 0;    //进行判断是否发生交换
            while (cur)
            {
                if (p->data > cur->data)
                {
                    swap(&(p->data), &(cur->data));
                    exchange = 1;
                }
                cur = cur->next;
                p   = p->next;
            }
            if (exchange == 0)  //一趟循环结束未发生交换则return,跳出死循环                        
            {
                return;
            }
        }
    }
}




ListNode* Merge_List(ListNode* l1, ListNode* l2)   //合并两个有序的单链表,仍有序
{
    if (NULL == l1 || NULL == l2)        //判断两个链表是否为空
    {
        return l1 == NULL ? l2 : l1;    //返回非空的链表或者空链表
    }
    ListNode* newhead = CreatNode(0);    //创建一个头结点,之后再进行free
    ListNode* l = newhead;
    ListNode* cur1 = l1;
    ListNode* cur2 = l2;
    while (cur1 && cur2)
    {
        if (cur1->data > cur2->data)
        {
            l->next = cur2;
            l = l->next;
            cur2 = cur2->next;
        }
        else
        {
            l->next = cur1;
            l = l->next;
            cur1 = cur1->next;
        }
    }
    l->next= (cur1 == NULL ? cur2 : cur1);
    ListNode* tmp = newhead;
    newhead = newhead->next;
    free(tmp);
    tmp = NULL;
    return newhead;

}




ListNode* Joseph_Cycle(ListNode* head,int k)        //约瑟夫环
{
    if (NULL == head)
    {
        printf("list is empty!\n");
        return NULL;
    }
    
    ListNode* cur = head;
    while (cur->next != NULL)
    {
        cur = cur->next;
    }
    ListNode* tmp = NULL;
    cur->next = head;
    cur = head;
    int count = k;
    while (1)
    {
        count = k;
        if (cur->next != cur)
        {
            while (--count)
            {
                cur = cur->next;
            }
            tmp = cur->next;
            cur->data = cur->next->data;
            cur->next = cur->next->next;
            free(tmp);
        }
        else
        {
            cur->next = NULL;
            return cur;
        }
    }
}




ListNode* CreatCycle(ListNode* phead,int k)        //为单链表创造一个环
{
    if (NULL == phead)            //phead为空
    {
        printf("list is empty!\n");
        return NULL;
    }
    ListNode* pos = Find(&phead, k);
    if (pos == NULL)
    {
        printf("k is error!\n");
    }

    ListNode* pos1 = pos;
    ListNode* tail = phead;
    while (tail->next)            //找到list的尾节点
    {
        tail = tail->next;
    }
    tail->next = pos1;            //list的尾节点*next指向pos 
    tail = phead;                //cur 指向头结点
    return tail;
}




int IsLoop(ListNode* phead)            //判断链表是否有环,有环返回1;否则返回-1;
{
    if (NULL == phead)
    {
        printf("list is empty!\n");
        return -1;
    }
    ListNode* slow = phead;    //快指针 
    ListNode* fast = phead;    //慢指针
    while (fast && fast->next)    
    {
        fast = fast->next->next;    //fast = 2*slow
        slow = slow->next;
        if (&slow->data == &fast->data)
        {
            return 1;
        }
    }
    return -1;
}



ListNode* MeetNode(ListNode* phead)        //返回快慢指针在环中相遇的节点,同时也可以判断是否存在环
{
    if (NULL == phead)
    {
        printf("list is empty!\n");
        return -1;
    }
    ListNode* slow = phead;    //快指针 
    ListNode* fast = phead;    //慢指针
    while (fast && fast->next)
    {
        fast = fast->next->next;    //fast = 2*slow
        slow = slow->next;
        if (&slow->data == &fast->data)            //if(slow == fast);
        {
            return slow;
        }
    }
    return NULL;
}




int GetLength(ListNode* phead)        //求单链表的节点个数
{
    int count = 0;
    ListNode* cur = phead;
    if (NULL == phead)        //空表
    {
        return count;
    }
    else                //非空表    
    {
        while (cur)
        {
            cur = cur->next;
            count++;
        }
        return count;
    }
}



ListNode* GetEnterNode(ListNode* phead)        //求有环单链表的环的入口节点
{
    ListNode* meet = MeetNode(phead);    //判断list是否存在环

    if (NULL == meet)                    //没有环的情况
    {
        printf("there is no cycle in the list!\n");    
        return NULL;
    }
    else                                //有环的情况
    {
        ListNode* tar = meet;
        ListNode* cur = phead;
        while (tar != cur)            //2*(L + X)=L + X + nC   L = nC - X
        {
            cur = cur->next;
            tar = tar->next;
        }
        return cur;            //返回环入口节点
    }
}


本文出自 “木木侠” 博客,请务必保留此出处http://10324228.blog.51cto.com/10314228/1715722

单链表的函数实现

原文:http://10324228.blog.51cto.com/10314228/1715722

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!