单链表(c语言版)

SList.h

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

typedef int DataType ;
typedef struct Node
{
    DataType data;
    struct Node* next;
}Node, *PLinkList;
void InitList(PLinkList* pplist); //初始化
void PrintList(PLinkList* pplist);  //打印
int GetLength(PLinkList plist);//求长度
void PushBack(PLinkList* pplist, DataType x);//尾插
void PushFront(PLinkList* pplist, DataType x);//头插
void PopFront(PLinkList* pplist);//头删
void PopBack(PLinkList* pplist);//尾删
Node* Find(PLinkList plist, DataType x);
void Insert(PLinkList* pplist, Node * n, DataType x);
void InsertFrontNode(Node *n, DataType x);
void Reverse(PLinkList *pplist); // 翻转
void sort(PLinkList *plist);//排序
void PrintTailToHead(PLinkList plist);

PLinkList _CreateNode(DataType x)
{
    PLinkList tmp = (PLinkList)malloc(sizeof(Node));
    tmp->data = x;
    tmp->next = NULL;
    return tmp;
}

void InitList(PLinkList* pplist)
{
    assert(pplist);
    *pplist = 0;
}
void PrintList(PLinkList* pplist)
{
    PLinkList begin = *pplist;
    assert(pplist);
    while (begin != NULL)
    {
        printf("%d->", begin->data);
        begin = begin->next;
    }
    printf("NULL\n");
}
void PushBack(PLinkList* pplist, DataType x)
{
    PLinkList tmp;
    PLinkList begin = *pplist;
    assert(pplist);
    if (*pplist == NULL)
    {
        *pplist = _CreateNode(x);
    }
    else
    {
        tmp = _CreateNode(x);
        while (begin->next != NULL)
        {
            begin = begin->next;
        }
        begin->next = tmp;
        tmp->next = NULL;
    }

}
void PushFront(PLinkList* pplist, DataType x)
{
    PLinkList tmp;
    assert(pplist);
    if (*pplist == NULL)
    {
        *pplist = _CreateNode(x);
    }
    else
    {
        tmp = _CreateNode(x);
        tmp->next = *pplist;
        *pplist = tmp;
    }
}
int GetLength(PLinkList plist)
{
    int count = 0;
    PLinkList begin = plist;
    assert(plist);
    while (begin != NULL)
    {
        begin = begin->next;
        count++;
    }
    return count;
}
void PopFront(PLinkList* pplist)
{
    PLinkList tmp;
    assert(pplist);
    if (*pplist == NULL)
    {
        printf("SList is empty\n");
        return;
    }
    else
    {
        tmp = *pplist;
        *pplist = (*pplist)->next;
        free(tmp);
    }
}
void PopBack(PLinkList* pplist)
{
    PLinkList prev = *pplist,end = *pplist;
    assert(pplist);
    if (*pplist == NULL)
    {
        printf("SList is empty\n");
        return;
    }
    else if ((*pplist)->next == NULL)//只有一个节点
    {
        free(*pplist);
        *pplist = NULL;
        printf("delet success\n");
        return;
    }
    else //有多个节点
    {
        while (end->next != NULL)
        {
            prev = end;
            end = end->next;
        }
        prev->next = NULL;
        free(end);
    }
}
Node* Find(PLinkList plist, DataType x)
{
    PLinkList begin = plist;
    assert(plist);
    if (plist == NULL)
    {
        printf("SList is empty\n");
        return begin;
    }
    else 
    {
        while (begin != NULL)
        {
            if (begin->data == x)
            {
                printf("find %d\n", x);
                return begin;
            }

            begin = begin->next;
        }
    }
    printf("not find %d\n", x);
    return NULL;
}

void Insert(PLinkList* pplist, Node * n, DataType x)
{
    PLinkList tmp;
    assert(pplist);
    if (*pplist == NULL)
    {
        *pplist = _CreateNode(x);
        return;
    }
    else
    {
        tmp = _CreateNode(x);
        tmp->next = n->next;
        n->next = tmp;
    }
}
void DelMidNode(Node* n)
{
    assert(n);
    if ( n == NULL)
    {
        printf("node is NULL\n");
        return;
    }
    else if (n->next == NULL)
    {
        printf("n is trail node\n");
    }
    else
    {
        Node* tmp = n->next;
        n->data = tmp->data;
        n->next = tmp->next;
        free(tmp);
    }
}
int Remove(PLinkList* pplist, Node * n)
{
    assert(pplist);

     if ((n->next) == NULL)
    {
         PopBack(pplist);
        return 0;
    }
     else
     {
         DelMidNode(n);
         return 0;
     }
}
void Erase(PLinkList* pplist, DataType x, int all)
{
    Node* ret = *pplist;
    assert(pplist);
    do
    {
         ret = Find(ret,x);
        if (ret != NULL)
        {
            Remove(pplist, ret);
        }
    } while (ret != 0 && all != 0);
   }

void InsertFrontNode(Node *n, DataType x)
{
    Node *tmp;
    assert(n);
    if (n == NULL)
    {
        printf("n is NULL\n");
        return;
    }
    else
    {
        tmp = _CreateNode(n->data);
        tmp->next = n->next;
        n->next = tmp;
        n->data = x;
    }
}

//逆置/反转单链表
void Reverse(PLinkList *pplist)
{
    Node* NewHead = NULL;
    Node* begin = (*pplist)->next;
    assert(pplist);
    if (*pplist != NULL)
    {
        // 取第一个节点做新的头结点
        NewHead = *pplist;
        NewHead->next = NULL;
    }
    while (begin != NULL)
    {
        // 取节点进行头插
        Node* tmp = begin;
        begin = begin->next;
        tmp->next = NewHead;
        NewHead = tmp;
    }
    *pplist = NewHead;
}

//链表排序
void sort(PLinkList *pplist) 
{
    int count = 0;
    int exchange = 0;
    PLinkList tmp = *pplist;
    assert(pplist);
    if (*pplist == NULL)
    {
        printf("SList is empty\n");
        return;
    }
    else
    {
        while (count < GetLength(*pplist))
        {
            exchange = 0;
           while (tmp->next != NULL)
            {
               if (tmp->data > tmp->next->data)
                {

                   DataType x = tmp->data;
                   tmp->data = tmp->next->data;
                   tmp->next->data = x;
                   exchange = 1;
                }
                tmp = tmp->next;
            }
           if (exchange == 0)
           {
               return;
           }
            tmp = *pplist; //又从头开始检查
            count++;
        }
    }
}

//从尾到头打印单链表
void PrintTailToHead(PLinkList pList)
{
    if(pList)
    {
        PrintTailToHead(pList->next); //递归调用
        printf("%d->", pList->data);
    }

}

//单链表实现约瑟夫环
void JosephCycle(PLinkList* ppList, int k)
{
    Node* begin = *ppList;
    assert(ppList);
    if (*ppList == NULL)
    {
        return;
    }
    else
    {
        while (1)
        {
            if (begin->next == begin) //只剩下一个节点
            {
                break;
            }
            Node* del = NULL;
            int x = k;
            while (--x)
            {
                begin = begin->next;
            }
            //应用删除一个无头无尾的中间节点的思想
            printf("delete node is %d\n", begin->data);
            begin->data = begin->next->data; 
            del = begin->next;
            begin->next = del->next;
            free(del);
        }
        *ppList = begin;
    }
}

//合并两个有序链表,合并后依然有序
PLinkList Merge(PLinkList pList1, PLinkList pList2)
{
    PLinkList pList = pList1; //新的头节点
    PLinkList end;
    assert(pList1);
    assert(pList2);
    if (pList1 == NULL)
    {
        return pList2;
    }
    if (pList2 == NULL)
    {
        return pList1;
    }
    if (pList1 == pList2)
    {
        return pList1;
    }
    //选择一个小的作为头节点
    if (pList1->data < pList2->data)
    {
        pList = pList1;
        pList1 = pList1->next;
    }
    else
    {
        pList = pList2;
        pList2 = pList2->next;
    }
    end = pList; //链接下一个节点
    while (pList1 && pList2)
    {
        Node* tmp = NULL;
        if (pList1->data < pList2->data)
        {
            tmp = pList1;
            pList1 = pList1->next;
        }
        else
        {
            tmp = pList2;
            pList2 = pList2->next;
        }
        end->next = tmp;
        end = tmp;
    }
    if (pList1)
    {
        end->next = pList1;
    }
    if (pList2)
    {
        end->next = pList2;
    }
    return pList;
}

//查找单链表的中间节点,要求只能遍历一次链表
Node* FindMidNode(PLinkList *ppList)
{
    PLinkList slow = *ppList;
    PLinkList fast = *ppList;
    assert(ppList);
    if (*ppList == NULL)
    {
        return NULL;
    }
    else
    {
        while (fast && fast->next)
        {
            fast = fast->next->next; //快指针一次走两步
            slow = slow->next;      //慢指针一次走一步
        }
        printf("MidNode is %d\n", slow->data);
        return slow;
    }
}

//查找单链表的倒数第k个节点,要求只能遍历一次链表
Node* FindKNode(PLinkList *ppList,DataType k)
{
    int x = k;
    PLinkList slow = *ppList;
    PLinkList fast = *ppList;
    assert(ppList);
    if (*ppList == NULL)
    {
        return NULL;
    }
    else
    {
        while (fast && x--) //快指针先走k步
        {
            fast = fast->next;
        }
        if (x > 0)//链表总共都没有k个节点
        {
            return NULL;
        }
        while (fast)  //当快指针走到结尾慢指针走到倒数第k个节点
        {
            fast = fast->next;
            slow = slow->next;
        }
        printf("The last %d node is %d\n", k, slow->data);
        return slow;
    }
}

//判断单链表是否带环
bool IsCycle(PLinkList pList, PLinkList *ppMeetNode) 
{
    assert(pList);
    PLinkList slow = pList;
    PLinkList fast = pList;
    while (fast && fast->next)
    {
        fast = fast->next->next;
        slow = slow->next;
        if (fast == slow)
        {
            *ppMeetNode = slow;
            return true;
        }
    }
    *ppMeetNode = NULL;
    return false;
}



main.cpp

#include"Slist.h"
void test()
{
    int ret;
    PLinkList plist;
    InitList(&plist);
    PushFront(&plist, 1);
    PushFront(&plist, 2);
    PushFront(&plist, 3);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PrintList(&plist);
    PopFront(&plist);
    PrintList(&plist);
    PopBack(&plist);
    PrintList(&plist);
    PopBack(&plist);
    PrintList(&plist);
    PopBack(&plist);
    Find(plist, 4);
    ret = GetLength(plist);
    printf("length= %d\n", ret);
}
void test2()
{
    PLinkList ret;
    PLinkList plist;

    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PrintList(&plist);
    ret = Find(plist, 1);
    if (ret != NULL)
    {
        Insert(&plist, ret, 10);
    }
    PrintList(&plist);
}
void test3()
{
    PLinkList ret;
    PLinkList plist;
    Node* no = NULL;
    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PrintList(&plist);
    ret = Find(plist, 3);
    DelMidNode(ret);
    PrintList(&plist);
    ret = Find(plist, 1);
    Remove(&plist, ret);
    PrintList(&plist);
}
void test4()
{
    PLinkList plist;
    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 1);
    PushBack(&plist, 1);
    PushBack(&plist, 3);
    PrintList(&plist);
    Erase(&plist, 1, 0);
    PrintList(&plist);
    Erase(&plist, 1, 1);
    PrintList(&plist);
}
void test5()
{
    PLinkList plist,ret;
    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PrintList(&plist);
    ret = Find(plist, 2);
    InsertFrontNode(ret, 10);
    PrintList(&plist);
    Reverse(&plist);
    PrintList(&plist);
    PrintTailToHead(plist);
}
void test6()
{
    PLinkList plist;
    InitList(&plist);
    PushBack(&plist, 6);
    PushBack(&plist, 4);
    PushBack(&plist, 2);
    PushBack(&plist, 1);
    PushBack(&plist, 5);
    PushBack(&plist, 3);
    PrintList(&plist);
    sort(&plist);
    PrintList(&plist);
    PrintTailToHead(plist);
}
void test7()
{
    PLinkList plist,ret;
    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 4);
    PushBack(&plist, 5);
    PushBack(&plist, 6);
    PrintList(&plist);
    //构建约瑟夫环
    ret = Find(plist, 6);
    ret->next = plist;
    JosephCycle(&ret, 3);

}
void test8()  
{
    PLinkList plist, plist1, plist2;
    InitList(&plist1);
    PushBack(&plist1, 1);
    PushBack(&plist1, 2);
    PushBack(&plist1, 4);
    PushBack(&plist1, 6);
    PushBack(&plist1, 9);
    PushBack(&plist1, 10);
    PrintList(&plist1);

    InitList(&plist2);
    PushBack(&plist2, 3);
    PushBack(&plist2, 5);
    PushBack(&plist2, 7);
    PushBack(&plist2, 8);
    PushBack(&plist2, 14);
    PushBack(&plist2, 17);
    PrintList(&plist2);
    plist = Merge(plist1, plist2);
    PrintList(&plist);
    FindMidNode(&plist);
    FindKNode(&plist, 4);
}
void test9()
{
    char *tag = NULL;
    Node* entry, *end, *pMeetNode;
    PLinkList plist;
    InitList(&plist);
    PushBack(&plist, 1);
    PushBack(&plist, 2);
    PushBack(&plist, 3);
    PushBack(&plist, 4);
    PushBack(&plist, 5);
    PushBack(&plist, 6);
    PrintList(&plist);
    entry = Find(plist, 4);
    end = Find(plist, 6);
    end->next = entry;
    *tag = IsCycle(plist, &pMeetNode);
    printf("Is Cycle %s\n",*tag);
}
int main()
{
    test9();
    getchar();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值