链表题

SList.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int DataType;
typedef struct SList
{
    DataType data;
    struct SList *p_next;


}SList,*PNode;


void SListInit(PNode* pHead);// 链表的初始化 


void SListPushBack(PNode* pHead, DataType data);// 尾插


void SListPopBack(PNode* pHead);// 尾删 


void SListPushFront(PNode* pHead, DataType data);// 头插 


void SListPopFront(PNode* pHead);// 头删 


PNode SListFind(PNode pHead, DataType data);// 在链表中查找值为data的元素,找到后返回值为data的结点


void SListInsert(PNode* pHead, PNode pos, DataType data);// 在pos位置插入值为data的结点


void SListErase(PNode* pHead, PNode pos);// 删除pos位置的结点 


int SListSize(PNode pHead);// 获取链表的长度 


int SListEmpty(PNode pHead);// 判断链表是否为空 


void SListDestroy(PNode* pHead);// 销毁聊表 


void PrintSList(PNode pHead);//打印链表的值


void PrintListTailToHead(PNode pHead);//逆序打印链表值


void DelNotTailNode(PNode pos);//删除链表节点


void InsertNotHead(PNode pos, DataType data);//在无头单链表的一个非头节点前插入一个节点


void FormCyc(PNode *pHead);//使链表形成一个环


PNode JosephCircle(PNode pHead, int M);//约瑟夫环


void yuesefu(PNode pHead,PNode pCur);//约瑟夫环输出


PNode FindelastkNode(PNode pHead,int k);//找到倒数第K个节点


void printfzhizhen(PNode pHead);//打印指针位置元素的值


void delastkNode(PNode pHead,int k);//删除倒数第K个节点


PNode FindelastkNode2(PNode pHead,int k);//返回前一个节点


void ReverseSList(PNode* pHead);//逆序链表


void maopao(PNode *pHead);//冒泡排序



SList.c


#include"SList.h"
PNode BuyNewNode(DataType data)
{
    PNode pCur = NULL;
    pCur = (PNode )malloc(sizeof(SList));
    pCur->data = data;
    return pCur;
}
void SListInit(PNode* pHead)// 链表的初始化 
{
    *pHead = NULL;


}
void SListPushBack(PNode* pHead, DataType data)// 尾插
{
    PNode pCur = NULL;
    PNode pRet = NULL;
    assert(pHead);
    if (*pHead == NULL)
    {
        *pHead =BuyNewNode(data);
        (*pHead)->p_next = NULL;
        return;
    }
    else
    {
        pCur = *pHead;
        while (pCur->p_next)
        {
            pCur = pCur->p_next;
        }
        pRet = BuyNewNode(data);
         pCur->p_next= pRet;
         pRet->p_next = NULL;
    }
    return;
}
void SListPopBack(PNode* pHead)// 尾删
{
    PNode pCur = *pHead;
    PNode pPre = NULL;
    assert(pHead);
    if (*pHead == NULL)
    {
        printf("链表已空,无法删除!!!\n");
        return;
    }


    while (pCur->p_next)
    {
        pPre = pCur;
        pCur = pCur->p_next;
    }
    pPre->p_next = NULL;
    free(pCur);


#if 0
    while (pCur->p_next->p_next)
    {
        pCur = pCur->p_next;
    }
    PNode pNext = NULL;
    pNext = pCur->p_next;
    pCur->p_next = NULL;
    free(pNext);
#endif
}




void SListPushFront(PNode* pHead, DataType data)// 头插 
{
    PNode pCur = *pHead;
    PNode pRet = NULL;
    assert(pHead);
    if (*pHead == NULL)
    {
        *pHead = BuyNewNode(data);
        (*pHead)->p_next = NULL;
    }
    else
    {
        pRet = BuyNewNode(data);
        pRet->p_next = pCur;
        *pHead = pRet;
    }
}
void SListPopFront(PNode* pHead)// 头删 
{
    PNode pCur = NULL;
    //判断pHead是否合法
    assert(pHead);
    //检测链表是否为空
    if (NULL == *pHead)
    {
        printf("链表为空,无法删除!!!\n");
        return;
    }
    else
    {
        //链表不为空
        pCur = *pHead;
        *pHead = (*pHead)->p_next;
        free(pCur);
    }
}
PNode SListFind(PNode pHead, DataType data)// 在链表中查找值为data的元素,找到后返回值为data的结点
{
    PNode pCur = pHead;
    //检测链表是否为空
    if (pHead == NULL)
    {
        printf("链表中无元素!!!\n");
        return NULL;
    }
    //链表不为空
    while (pCur)
    {
        if (pCur->data == data)
            return pCur;
        pCur = pCur->p_next;
    }
    return NULL;
}
void SListInsert(PNode* pHead, PNode pos, DataType data)// 在pos位置插入值为data的结点
{
    PNode pCur = *pHead;
    PNode pRet = NULL;
    PNode pPre = NULL;
    //检测pHead合法性
    assert(pHead);
    //链表为空
    if (*pHead == NULL )
    {
        printf("链表为空,无法插入!!!\n");
        return;
    }
    if (pos == NULL)
    {
        printf("插入位置无效,无法插入!!!\n");
    }
    else
    {
        //链表不为空
        pCur = *pHead;
        while(pCur!=pos&&pCur)      
        {
            pPre = pCur;
            pCur = pCur->p_next;
        }
        if (pCur == NULL)
        {
            printf("链表中无该位置,无法插入!!!\n");
            return;
        }
        else
        {
            pRet = BuyNewNode(data);
            pRet->p_next = pCur;
            pPre->p_next = pRet;
        }
    }
    return;
}
void SListErase(PNode* pHead, PNode pos)// 删除pos位置的结点 
{
    PNode pCur = *pHead;
    PNode pPre = NULL;
    assert(pHead);
    if (*pHead == NULL)
    {
        printf("链表为空,无法删除!!!\n");
        return;
    }
    while (pCur != pos&&pCur)
    {
        pPre = pCur;
        pCur = pCur->p_next;
    }
    if (!pCur)
    {
        printf("链表中无该结点!!!\n");
        return;
    }
    else
    {
        pPre->p_next = pCur->p_next;
        free(pCur);
    }
}
int SListSize(PNode pHead)// 获取链表的长度
{
    PNode pCur = pHead;


    int count = 0;
    if (pHead == NULL)
        return  0;
    while (pCur)
    {
        count++;
        pCur = pCur->p_next;
    }
    return count;
}


int SListEmpty(PNode pHead)// 判断链表是否为空 
{
    if (pHead == NULL)
        return 0;
    else return 1;
}
void SListDestroy(PNode* pHead)// 销毁聊表 
{
    PNode pCur = *pHead;
    PNode pPre = NULL;
    assert(pHead);
    if (*pHead == NULL)
        return;
    while (pCur)
    {
        pPre = pCur;
        pCur = pCur->p_next;    
        free(pPre);
    }
    *pHead = NULL;
}
void PrintSList(PNode pHead)//打印链表的值
{
    PNode pCur = NULL;
    pCur = pHead;
    while (pCur)
    {
        printf("%d ", pCur->data);
        pCur = pCur->p_next;
    }
    printf("\n");
}
//逆序打印链表
//原理:通过函数自己调用自己,
void PrintListTailToHead(PNode pHead)
{
if(pHead != NULL)
{
PrintListTailToHead(pHead->p_next);
//执行到这里返回,直到next为空,为空进入
//下一个if else 表达式,返回时候的函数就返回到这里继续执行


if(pHead->p_next == NULL)
printf("%d",pHead->data);
else
{
printf("->%d",pHead->data);

}

}

}
//删除一个无头单链表的非尾节点
void DelNotTailNode(PNode pos)
{
PNode cur = NULL;

assert(pos);
if(NULL == pos ->p_next)
return;
else
{
DataType temp = 0;
//交换pos和pos->n_next的数据,问题变成删除pos指向的节点的下一个节点
temp = pos->data;
pos->data = pos->p_next->data;
pos->p_next->data = temp;
cur = pos->p_next;
pos->p_next = pos->p_next->p_next;
        free(cur);
        cur = NULL;
}


}




void InsertNotHead(PNode pos, DataType data)//在无头单链表的一个非头节点前插入一个节点
{
PNode cur;
DataType i;
assert(pos);

i = pos->data;
pos->data = data;
data = i;
cur = BuyNewNode(data);
cur->p_next = pos->p_next;
pos->p_next = cur;


}


void FormCyc(PNode *pHead)//使链表形成一个环
{
PNode cur = *pHead;
assert(pHead);




while(cur->p_next)
{

cur = cur->p_next;
}
cur ->p_next = (*pHead);

}




PNode JosephCircle(PNode pHead, int M)//约瑟夫环
{

PNode cur = pHead;
PNode per = NULL;
PNode der = NULL;
DataType temp = M;
if ((NULL == pHead) || (M <=0))
    {
        return NULL;
    }
else
{
FormCyc(&pHead);
while(cur->p_next != cur)
{
temp = M;
per = cur;
while(temp)
{
per = cur;
cur = cur ->p_next;
--temp;
}
der = cur;
cur = cur->p_next;
per->p_next = cur;
free(der);
der = NULL;


}
 
if(M == 1)
{
free(cur);
cur = NULL;
return NULL;
}
else
{
cur -> p_next = NULL;

}
return cur;
}


}


void yuesefu(PNode pHead,PNode pCur)//约瑟夫环输出
{


PNode t = pHead;
if(pCur == NULL)
 {
 printf("输入错误或输入为1,剩下的节点为%d\n ",t->data);
 }
 else
 {
 printf("剩余的节点为%d\n",pCur->data);
 }
 


}


PNode FindelastkNode(PNode pHead,int k)
{
PNode pFast = pHead;
PNode last = pHead;
if(pHead == NULL || k <=0 )
{
return NULL;


}
while(k--)
{
if(pFast == NULL)
{
printf("K大于链表中节点个数");
return NULL;
}
pFast = pFast->p_next;
}


//慢指针一起走
while(pFast)
{
last = last->p_next;
pFast = pFast->p_next;
}
return last;


}


PNode FindelastkNode2(PNode pHead,int k)//返回前一个节点
{
PNode pFast = pHead;
PNode last = pHead;
PNode per = NULL;


if(pHead == NULL || k <=0 )
{
return NULL;


}
while(k--)
{
if(pFast == NULL)
{
printf("K大于链表中节点个数");
return NULL;
}
pFast = pFast->p_next;
}


//慢指针一起走
while(pFast)
{
per = last;
last = last->p_next;
pFast = pFast->p_next;
}
return per;


}
void printfzhizhen(PNode t)//打印指针位置元素的值
{
printf("节点值为%d\n",t->data);


}


void delastkNode(PNode pHead,int k)//删除倒数第K个节点
{
PNode cur;
PNode pur;
cur = FindelastkNode2(pHead,k);
pur = cur->p_next;
cur ->p_next = pur->p_next;
free(pur);

}


void ReverseSList(PNode* pHead)
{
PNode pur,cur,tur;
assert(pHead);
pur = NULL;
cur = *pHead;
tur = NULL;
while(cur)
{
tur = cur->p_next;
cur->p_next = pur;
pur = cur;
cur = tur;
}
(*pHead) = pur;

}
void maopao(PNode *pHead)
{
PNode pur,cur,tur;
int i;
int max = 0;
pur = NULL;
tur = (*pHead);







while(tur)
{
cur = *pHead;
max = cur->data;




while(cur)
{

if(cur->p_next == NULL)
break;



if( cur->p_next->data < cur->data)
{
max = cur->data;
cur ->data = cur->p_next->data;
cur->p_next->data = max;
}

cur = cur->p_next;

}


tur = tur->p_next;


}
}


Test.c

#include"SList.h"
int main()
{
    SList List;
    PNode  pHead ;


    PNode  pCur = NULL;


    SListInit(&pHead);//链表初始化
    //尾插测试
    SListPushBack(&pHead, 5);
    SListPushBack(&pHead, 6);
    SListPushBack(&pHead, 7);
    SListPushBack(&pHead, 8);
    SListPushBack(&pHead, 9);
    PrintSList(pHead);  //打印
    //头插测试
    SListPushFront(&pHead, 4);  
    SListPushFront(&pHead, 3);
    SListPushFront(&pHead, 2);
    SListPushFront(&pHead, 1);
    SListPushFront(&pHead, 0);
    PrintSList(pHead);  //打印
//PrintListTailToHead(5);
PrintListTailToHead(pHead);//逆序打印
printf("\n");



pCur = SListFind(pHead, 2); //先获取pos位置


DelNotTailNode(pCur);


 PrintSList(pHead);




 pCur = SListFind(pHead, 3);


 InsertNotHead(pCur, 8);//在无头单链表的一个非头节点前插入一个节点


 PrintSList(pHead);


  /*ReverseSList(&pHead);


  printf("haha");*/


  PrintSList(pHead);


  maopao(&pHead);


  PrintSList(pHead);



  
// pCur = JosephCircle(pHead, 8);


//  yuesefu(pHead,pCur);//约瑟夫环的输出


// pCur = FindelastkNode(pHead,5);


// printfzhizhen(pCur);


//   PrintSList(pHead);


//delastkNode(pHead,9);//删除倒数第K个节点


//PrintSList(pHead);

















    任意位置插入测试
   // pCur = SListFind(pHead, 2); //先获取pos位置


    //SListInsert(&pHead, pCur, 10); PrintSList(pHead);//打印


    //SListInsert(&pHead, NULL, 100); PrintSList(pHead);//打印


    任意位置删除
    //pCur = SListFind(pHead, 10);
    //SListErase(&pHead, pCur); PrintSList(pHead); //打印
    尾删测试
    //SListPopBack(&pHead); PrintSList(pHead);//打印
    头删测试
    //SListPopFront(&pHead); PrintSList(pHead);//打印
    打印链表的长度
    //printf("链表长度是:%d\n",SListSize(pHead));
    判断链表是否为空
    //printf("链表是否为空:%d\n", SListEmpty(pHead));
    销毁链表
    //SListDestroy(&pHead);
    再次判断是否为空
    //printf("链表是否为空:%d\n", SListEmpty(pHead));
    system("pause");
    return 0;
}



























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值