千家信息网

c#如何实现单向链表的查删改功能

发表于:2024-11-14 作者:千家信息网编辑
千家信息网最后更新 2024年11月14日,这篇文章主要介绍了c#如何实现单向链表的查删改功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。slist.h//头文件#ifndef
千家信息网最后更新 2024年11月14日c#如何实现单向链表的查删改功能

这篇文章主要介绍了c#如何实现单向链表的查删改功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

slist.h//头文件

#ifndef _SLIST_H_#define _SLTST_H_#include#include#include#includetypedef int SLTDataType; typedef struct SListNode {     SLTDataType data;        struct SListNode* next;}SListNode;void SListInit(SListNode** pphead);void SListDestory(SListNode** pphead);SListNode* BuySListNode(SLTDataType x);void SListPushFront(SListNode** pphead, SLTDataType x);void SListPopFront(SListNode** pphead);SListNode* SListFind(SListNode* pphead, SLTDataType x); // 在pos的后面进行插入 void SListInsertAfter(SListNode* pos, SLTDataType x); // 在pos的前面进行插入 void SListEraseAfter(SListNode* pos); void SListRemove(SListNode** pphead, SLTDataType x);void SListRemoveAll(SListNode** pphead, SLTDataType x);void SListPrint(SListNode* pphead);void SListReverse(SListNode **pphead);void SListReverse2(SListNode **pphead);SListNode* getIntersectionNode(SListNode* headA, SListNode*headB);SListNode *detectCycle(SListNode *head);#endif

slist.c//源文件

#include"slist.h"void SListInit(SListNode** pphead)//初始化{    *pphead = NULL;}void SListDestory(SListNode** pphead){    if (*pphead == NULL)    {        return;    }    else    {        while ((*pphead)->next)        {            SListEraseAfter(*pphead);        }        free(*pphead);        *pphead = NULL;    }}SListNode* BuySListNode(SLTDataType x){    SListNode* res = (SListNode *)malloc(sizeof(SListNode));    res->data = x;    res->next = NULL;    return res;}void SListPushFront(SListNode** pphead, SLTDataType x){    SListNode* tmp = BuySListNode(x);    tmp->next = *pphead;    *pphead = tmp;}void SListPopFront(SListNode** pphead){    if (*pphead == NULL)    {        return;    }    /*(*pphead)->date = (*pphead)->next;*/    SListNode* tmp = (*pphead)->next;    free(*pphead);    *pphead = tmp;}SListNode* SListFind(SListNode* pphead, SLTDataType x)//找x数据 {    SListNode* tmp;    for (tmp = pphead; tmp; tmp = tmp->next)    {        if (tmp->data == x)        {            return tmp;        }        return NULL;    }}void SListInsertAfter(SListNode* pos, SLTDataType x)//把x插到pos后面{    SListNode* tmp = BuySListNode(x);    tmp->next = pos->next;    pos->next = tmp;}void SListEraseAfter(SListNode* pos)//删除pos后面的数据{    SListNode* tmp = pos->next;    if (tmp == NULL)    {        return;    }    pos->next = tmp->next;    free(tmp);}void SListRemove(SListNode** pphead, SLTDataType x)//移除x{    SListNode* tmp;    if (*pphead == NULL)    {        return;    }    if ((*pphead)->data==x)    {        SListPopFront(*pphead);    }    else    {        for (tmp = *pphead; tmp->next; tmp = tmp->next)        {            SListEraseAfter(pphead);            return;        }    }}void SListRemoveAll(SListNode** pphead, SLTDataType x){    SListNode* tmp;    if (*pphead && (*pphead)->data == x)    {        SListPopFront(*pphead);    }    for (; tmp = *pphead; tmp&&tmp->next)    {        if (tmp->next == x)        {            SListEraseAfter(tmp);        }        else        {            tmp = tmp->next;        }    }}void SListPrint(SListNode* pphead){    SListNode* cur;    printf("pphead->");    for (cur = pphead; cur; cur = cur->next)    {        printf("%d->", cur->data);    }    printf("NULL\n");}void SListReverse(SListNode **pphead)//反转链表{    SListNode *head = *pphead;   //此指针在每次循环中始终指向当前链表的头    SListNode *tmp = head->next; //此指针在每次循环中始终指向要被后删头插的节点    SListNode *oldh = *pphead;   //此指针在每次循环中始终指向原本的头结点,不会改变指向    while (tmp) //如果tmp为空,则代表逆序结束,旧头的next已经是空的了,成为新链表的末尾    {        oldh->next = tmp->next; //将tmp架空,实际是后删操作的一部分        tmp->next = head; //让tmp变成新的头,实际是头插操作的一部分         head = tmp; //换头        tmp = oldh->next; //让tmp变成下次循环中待删除的节点    }    *pphead = head;}void SListReverse2(SListNode **pphead)//反转链表{    SListNode *pre = *pphead;   //被执行操作的前一个节点    SListNode *cur = pre->next; //被执行操作的节点    SListNode *next = cur;      //被执行操作的后一个节点,暂时指在cur,在循环开始的时候跳转到其后一个节点    pre->next = NULL; //此时的头,将会是转换后的尾,这里是在设置链表尾节点    while (next)    {        next = next->next; //先让next变成下一个节点,之所以不放在最后,是因为会有next为空的限制        cur->next = pre; //让原本指着后面的指到前面来(先后转)        pre = cur; //为了下次循环而传递数据,这里是设置下次循环的上一个节点(本次执行操作的节点将会成下次循环的上一个节点)        cur = next; //同上(本次的下一个节点将会成为下次的被执行节点)    }    *pphead = pre; //循环跳出后cur和next都已经指向空了,pre才是新的头}//输入两个链表,找出它们的第一个公共结点SListNode* getIntersectionNode(SListNode* headA, SListNode*headB){    int lenA = 0;    int lenB = 0;    int gap, i;    SListNode* cur = 0;    SListNode * longerlist = headA;    SListNode * shorterlist = headB;    for (cur = 0; cur; cur = headA->next)    {        lenA++;    }    for (cur = 0; cur; cur = headB->next)    {        lenB++;    }    gap = abs(lenA - lenB);    if (lenA > lenB)    {        longerlist = headA;        shorterlist = headB;    }    else    {        longerlist = headB;        shorterlist = headA;    }    for (i = 0; i < gap; i++)    {        longerlist=longerlist->next;    }    for (; longerlist&&shorterlist; longerlist = longerlist->next, shorterlist = shorterlist->next)    {        if (longerlist == shorterlist)        {            return longerlist;        }    }    return NULL;}// 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULLSListNode *detectCycle(SListNode *head){    SListNode * fast = head;    SListNode * slow = head;    while (fast && slow && fast->next)    {        fast = fast->next->next;//遍历速度为2        slow = slow->next;//遍历速度为1        if (fast == slow)//判断两不同遍历速度的交点        {            break;        }    }    for (; fast && fast->next; fast = fast->next, head = head->next)//交点到入环的第一个节点距离等于头节点到入环的第一个节点    {        if (fast == head)        {            return fast;        }    }    return NULL;}

main.c//测试

#include"slist.h"#if 0 //1,选择程序段int main()//测试{    SListNode *phead1;    //SListNode *phead2;    SListNode *tmp;    SListNode *tmp2;    SListInit(&phead1);    //SListInit(&phead2);    SListPushFront(&phead1, 8);    tmp = phead1;    SListPushFront(&phead1, 7);    SListPushFront(&phead1, 6);    SListPushFront(&phead1, 5);    SListPushFront(&phead1, 4);    SListPushFront(&phead1, 3);    tmp2 = phead1;    SListPushFront(&phead1, 2);    SListPushFront(&phead1, 1);    tmp->next = tmp2;    //phead2->next = phead1->next->next;    SListNode * ret = detectCycle(phead1);    if (ret)    {        printf("%d\n", ret->data);    }    else    {        printf("NULL\n");    }    //SListDestory(&phead1);    //SListDestory(&phead2);    return 0;}#elseint main()//测试{    SListNode *phead;    SListInit(&phead);    SListPushFront(&phead, 1);    SListPushFront(&phead, 2);    SListPushFront(&phead, 3);    SListPushFront(&phead, 4);    SListPushFront(&phead, 5);    SListPushFront(&phead, 6);    SListPushFront(&phead, 7);    SListPushFront(&phead, 8);    SListPushFront(&phead, 9);    //SListPopFront(&phead);    //SListPopFront(&phead);    /*    SListInsertAfter(SListFind(phead, 6), 9);    SListEraseAfter(SListFind(phead, 4));    SListRemove(&phead, 7);    SListPrint(phead);    */    //SListRemoveAll(&phead, 8);    SListReverse2(&phead);    SListPrint(phead);    SListDestory(&phead);    //SListPrint(phead);    return 0;}#endif//int main()//约瑟夫环问题,链表解决//{//  SListNode *phead;//  SListNode *plast;//  SListNode *cur;//  int m = 11, n = 3;//  int i;//  SListInit(&phead);//  SListPushFront(&phead, m);//  plast = phead;//  for (i = m - 1; i >= 1; i--)//  {//      SListPushFront(&phead, i);//  }//  plast->next = phead;//  cur = plast;//  for (; m > 1; m--)//  {//      for (i = 1; i < n; i++)//      {//          cur = cur->next;//          printf("%d号报数字%d\n", cur->data, i);//      }//      printf("%d号被去掉\n", cur->next->data);//      SListEraseAfter(cur);//  }//  printf("%d号最终获胜\n", cur->data);//  free(cur);//  return 0;//}

感谢你能够认真阅读完这篇文章,希望小编分享的"c#如何实现单向链表的查删改功能"这篇文章对大家有帮助,同时也希望大家多多支持,关注行业资讯频道,更多相关知识等着你来学习!

0