单链表的基本操作(面试题)


title:单链表的基本操作(面试题)

链表的基本操作是初学数据结构的必要练习,也是公司面试时的热门考点
以下是个人总结的不全面一些操作,在这里分享。
include<assert.h>
include<stdio.h>
include<stdlib.h>
include<malloc.h>

//#pragma warning (disable:4996);

typedef int DataType;

typedef struct Node{
struct Node* next;
DataType data;
}Node ,*PNode;

//初始化单链表
void InitList(PNode* pHead);
//创建一个新节点
PNode BueNode(DataType data); 
//尾插一个节点
void PushBack(PNode* pHead,DataType data); 
//尾删一个节点
void PopBack(PNode* pHead);  
//打印链表
void PrintList(PNode pHead); 
//从尾到头打印单链表
void PrintListFromTailtoHead(PNode pHead); 
//头插一个节点
void PushFront(PNode* pHead,DataType data); 
//头删一个节点
void PopFront(PNode* pHead); 
//寻找链表中第一个值域是data的节点
PNode Find(PNode pHead,DataType data);
//pos位置后插入
void Insert(PNode pos,DataType data); 
//pos位置前插入
void InsertNotHeadNode(PNode pos,DataType data);
//删除一个节点
void Erase(PNode* pHead,PNode pos);
void Remove(PNode* pHead , DataType data);
//删除一个无头单链表的非尾节点
void DeleteNotTailNode(PNode pos);
//删除所有值为data的节点
void RemoveAll(PNode* pHead , DataType data);
//得出链表大小
int Size(PNode pHead);
//找最后一个节点
PNode Back(pHead);
//判断两个个链表是否交叉 
int IsListCross(PNode pHead1,PNode pHead2);
//判断两个个链表是否交叉 并求交点
PNode GetCrossNode(PNode pHead1,PNode pHead2);
//是否带环
PNode HasCircle(PNode pHead);
//环周长
int GetCircleLen(PNode pMeetNode);
//判断两个可能带环的链表是否相交。
int IfCrossWithCricle(PNode pHead1,PNode pHead2);
//获得带环单链表的入口点
PNode GetEnterNode(PNode pHead,PNode pMeetNode);
//逆置单链表
PNode Reverse(PNode pHead);
//单链求解拟约瑟夫环(表已成环)
PNode Josephcircle(PNode pHead,int n);



void InitList(PNode* pHead)
{
    assert(pHead);
    *pHead = NULL;
}

PNode BueNode(DataType data)
{
   PNode pTemp = (PNode)malloc(sizeof(Node));
       if(pTemp)
       {
           pTemp->data = data;
           pTemp->next = NULL;
       }
       return pTemp;
}

void PushBack(PNode* pHead,DataType data)
{
    assert(pHead);

    if(NULL == *pHead)
        *pHead = BueNode(data);
    else{
    /*  PNode pCur = *pHead;
        while(pCur->next){
            pCur = pCur->next;
        }
        pCur->next = BueNode(data);*/
        PNode pCur = *pHead;
        PNode pPre = pCur;
        while(pCur){
            pPre = pCur;
            pCur = pCur->next;
        }
        pPre->next = BueNode(data);
    }

}

void PushFront(PNode* pHead,DataType data)
{
    PNode pNewNode = BueNode(data);
    assert(pHead);
    if(pNewNode){
    pNewNode->next = *pHead;
    *pHead = pNewNode;
    }
}

void PopFront(PNode* pHead)
{
    PNode pDel = NULL;
    assert(pHead);
    if(NULL == *pHead)
        return ;

    pDel = *pHead;
    *pHead = (*pHead)->next;
    free(pDel);

}

void PopBack(PNode* pHead)
{
    assert(pHead);
    if(NULL == *pHead){
          return ;
    }
    else if(NULL == (*pHead)->next){
        free(*pHead);
        *pHead = NULL;
    }
    else{
        PNode pCur = *pHead;
        PNode pNewTail = NULL;
        while(pCur->next->next){
            pCur = pCur->next;
        }
        pNewTail = pCur;
        free(pCur->next);
        pNewTail->next = NULL;
    }
}

void PrintList(PNode pHead)
{
    PNode pCur = pHead;
    while(pCur){
        printf("%d->",pCur->data);
        pCur = pCur->next;
    }
    printf("NULL");
    printf("\n");
}

//用递归思想解决
void PrintListFromTailtoHead(PNode pHead)
{
    //if(NULL == pHead){return ;}
    //PrintListFromTailtoHead(pHead->next);
    //printf("%d->",pHead->data);

    if(pHead){
    PrintListFromTailtoHead(pHead->next);
    printf("%d->",pHead->data);
    }
}   

PNode Find(PNode pHead,DataType data)
{
    PNode pCur = pHead;
    assert(pHead);
    while(pCur){
        if(pCur->data == data)
            return pCur;
        pCur = pCur->next;
    }
    return NULL;
}

void Insert(PNode pos,DataType data)
{
    PNode pNewNode = NULL;
    assert(pos);
    if(NULL == pos){return;}
    pNewNode = BueNode(data);
    pNewNode->next = pos->next;
    pos->next = pNewNode;
}

void Erase(PNode* pHead,PNode pos)
{
    assert(pHead);
    if(NULL == *pHead || NULL == pos)
        return;
    if(pos == *pHead){
        *pHead = pos->next;
        free(pos);
    }
    else{
        PNode pPre = *pHead;
        while(pPre->next != pos){
            pPre = pPre->next;
        }
        pPre->next = pos->next;
        free(pos);
    }

}
void DeleteNotTailNode(PNode pos)
{
    assert(pos);
    if(NULL == pos || NULL == pos->next)
        return ;
    pos->data = pos->next->data;
    pos->next = pos->next->next;

}

void InsertNotHeadNode(PNode pos,DataType data)
{    
    PNode pNewNode = BueNode(pos->data);
    if(NULL == pos )
        return ;
    if(pNewNode){
        pNewNode->next = pos->next;
        pos->next = pNewNode;
        pos->data = data;
    }

}

void Remove(PNode* pHead , DataType data)
{
    assert(pHead);
    Erase(pHead,Find(*pHead,data));
}

void RemoveAll(PNode* pHead , DataType data)
{
    PNode pPre = *pHead;
    PNode pCur = (*pHead)->next;
    assert(pHead);
    while(pCur)
    {
        if(pCur->data == data){
            pPre->next = pCur->next;
            free(pCur);
            pCur = pPre->next;
        }
        else{
        pCur = pCur->next;
        }
    }
    if((*pHead)->data == data)
    {
        pCur = *pHead;
        *pHead = (*pHead)->next;
        free(pCur);
    }
 }

int Size(PNode pHead)
{
    PNode pCurNode = pHead;
    int count = 0;
    while(pCurNode){
        count++;
        pCurNode = pCurNode->next;
    }
    return count;
}

PNode Back(PNode pHead)
{
    assert(pHead);
    while(pHead->next){
        pHead = pHead->next;
    }
    return pHead;
}

//////////////////////////////////////////
int IsListCross(PNode pHead1,PNode pHead2)
{
    PNode pTailNode1 = pHead1;
    PNode pTailNode2 = pHead2;
    if(NULL == pHead1||NULL == pHead2)
        return 0;
    while(pTailNode1->next)
        pTailNode1 = pTailNode1->next;
    while(pTailNode2->next)
        pTailNode2 = pTailNode2->next;
    if(pTailNode1 == pTailNode2)
        return 1;
    return 0;
}
//逻辑分析图:
![这里写图片描述]、、(http://img.blog.csdn.net/20170315001139787?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveF9fMDE2TWVsaW9yZW0=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
PNode GetCrossNode(PNode pHead1,PNode pHead2)
{
    int count1 = 0;
    int count2 = 0;
    PNode pL1 = pHead1;
    PNode pL2 = pHead2;
    int gap = 0;
     if(NULL == pHead1||NULL == pHead2)
        return 0;
     if(0 == IsListCross( pHead1, pHead2))
         return NULL;

     count1 = Size(pHead1);
     count2 = Size(pHead2);
     gap = count1 - count2;
     if(gap>0){
         while(gap--){
             pL1 = pL1->next;
         }
     }
     else{
         while(gap++){
             pL2 = pL2->next;
         }
     }
     while(pL1 != pL2){
             pL1 = pL1->next;
             pL2 = pL2->next;
     }
     return pL2; 
}

PNode HasCircle(PNode pHead)
{
    PNode pFast = pHead;
    PNode pSlow = pHead;
    assert(pHead);
    while(pFast &&  pFast->next)
    {
        pFast = pFast->next->next;
        pSlow = pSlow->next;
        if(pFast == pSlow){
        return pFast;
        }
    }
    return NULL;
}

int GetCircleLen(PNode pMeetNode)
{
    PNode pCurNode = pMeetNode ;
    int count = 1;
    if(NULL == pMeetNode)
        return 0;
    while(pCurNode->next != pMeetNode){
        count++;
        pCurNode = pCurNode->next;
    }
    return count;
}

PNode GetEnterNode(PNode pHead,PNode pMeetNode)
{
    PNode pH = pHead;
    PNode pM = pMeetNode;
    if(NULL == pHead||NULL == pHead->next)
        return 0;
    while(pH != pM){
        pH = pH->next;
        pM = pM->next;
    }
    return pH;
}

int IfCrossWithCricle(PNode pHead1,PNode pHead2)//判断两个可能带环的链表是否相交。
{
    PNode pMeetNode1 = HasCircle(pHead1);
    PNode pMeetNode2 = HasCircle(pHead2);
    if(NULL == pMeetNode1 && NULL == pMeetNode2){
        return IsListCross(pHead1,pHead2);//判断两个个链表是否交叉 
    }
    else if(pMeetNode1 && pMeetNode2){
            PNode pCur = pMeetNode1;
            while(pCur->next != pMeetNode2){
                if(pCur == pMeetNode2){
                    return 2;
                }
                pCur = pCur->next;
                if(pCur == pMeetNode1)
                    return 0;
            }
            if(pCur->next == pMeetNode2)
                return 2;
        }
    return 0;
}

PNode Reverse(PNode pHead)
{
    PNode pPre = pHead;
    PNode pCur = pHead->next;
    PNode pnext = pCur->next;
    if(NULL == pHead || NULL == pHead->next )
        return 0;
    while(pnext){
        pCur->next = pPre;
        pPre = pCur;
        pCur = pnext;
        pnext = pnext->next;
    }
    pCur->next = pPre;
    pHead->next = NULL;
    return pCur;
}

PNode Josephcircle(PNode pHead,int n)
{
    PNode pCur = pHead;

    if(NULL == pHead)
        return NULL;
    while(pCur->next != pCur){
        PNode pDel = pCur->next;
        int count = n;
        while(--count){
            pCur = pCur->next;
            pDel = pDel->next;
        }
        pCur->data = pDel->data;
        pCur->next = pDel->next;
        free(pDel);
    }
    return pCur;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值