单链表常见操作

#include <stdio.h>
#include <stdlib.h>

typedef struct Lnode
{
    int data;
    struct Lnode *next;
}Lnode;

//头插法实现单链表
Lnode* createLinkListByHead(int a[],int n)
{
    Lnode* head=(Lnode*)malloc(sizeof(Lnode));
    head->next=NULL;
    int i=0;
    for(i=0;i<n;i++)
    {
        Lnode* node=(Lnode*)malloc(sizeof(Lnode));
        node->data=a[i];
        node->next=head->next;
        head->next=node;
    }
    return head;
}
//尾插法实现单链表
Lnode* createLinkListByTail(int a[],int n)
{
    Lnode *head=(Lnode*)malloc(sizeof(Lnode));
    head->next=NULL;
    int i=0;
    Lnode *p=head;
    for(i=0;i<n;i++)
    {
        Lnode* node=(Lnode*)malloc(sizeof(Lnode));
        node->data=a[i];
        p->next=node;
        p=node;
    }
    p->next=NULL;
    return head;
}
//初步实现
Lnode* swapLinklist(Lnode *head)
{
    if(head==NULL || head->next==NULL)
        return head;
    Lnode *p=head;
    Lnode *pp=head->next;
    Lnode *pNext=NULL;
    Lnode *pre=NULL;
    while(pp!=NULL)
    {
        p->next=pp;
        pNext=pp->next;
        pp->next=pre;
        pre=pp;
        pp=pNext;
    }
    return p;
}

//上面方法的简单优化
Lnode* swapListLink(Lnode *head)
{
    if(head==NULL || head->next==NULL)
    {
        return head;
    }
    Lnode *p=head->next;
    Lnode *pNext=NULL;
    Lnode *pre=NULL;
    while(p!=NULL)
    {
        head->next=p;
        pNext=p->next;
        p->next=pre;
        pre=p;
        p=pNext;
    }
    return head;
}


//进一步优化
Lnode* swapList(Lnode *head)
{
    if(head==NULL || head->next==NULL)
        return head;
    Lnode *p=head->next;
    Lnode *pNext=NULL;
    head->next=NULL;
    while(p!=NULL)
    {
        pNext=p->next;
        p->next=head->next;
        head->next=p;
        p=pNext;
    }
    return head;
}

//链表k翻转,还有一种更方便的方法,就是遍历一遍把值保存在一个数组里面
//根据规则重新给链表赋值
void swapListByK(Lnode *head,int k)
{
    if(head==NULL || head->next==NULL)
    {
        return;
    }
    int i=0;
    Lnode *p=head->next;
    head->next=NULL;
    Lnode *pTail=head,*pHead=NULL,*pNext=NULL;
    while(p!=NULL)
    {
        if(i%k==0)
        {
            pHead=pTail;
            pTail=p;
        }
        pNext=p->next;
        p->next=pHead->next;
        pHead->next=p;
        p=pNext;
        i++;
    }
}

//假设两个单链表都没有环
int isCrossed(Lnode *p,Lnode *q)
{
    Lnode *pp=p,*qq=q;
    while(pp->next!=NULL)//注意pp->next!=null和pp!=null的区别,两种情况最后的点是不同的
        pp=pp->next;
    while(qq->next!=NULL)
        qq=qq->next;
    if(pp==qq)
        return 1;
    return 0;

}
//判断一个单链表是否自身有环
int isHaveCircle(Lnode *p)
{
    if(NULL==p || NULL==p->next)
        return 0;
    Lnode *low,*fast;
    low=p,fast=p;
    while(NULL!=fast && NULL!=fast->next)//条件判定的前后顺序很重要
    {
        low=low->next;
        fast=fast->next->next;
        if(low==fast)
            return 1;
    }
    return 0;
}
//可能有cycle(但是两个都有单独的环会无限循环)
int isTwoCrossed(Lnode *p,Lnode *q)
{
    if(!isHaveCircle(p) && !isHaveCircle(q))
        return isCrossed(p,q);
    if(!isHaveCircle(p) || !isHaveCircle(q))
        return 1;
    Lnode *pp=p,*qq=q;
    while(pp!=NULL && qq!=NULL && pp!=qq)
    {
        pp=pp->next;
        if(qq->next!=NULL)
            qq=qq->next->next;
        else
            qq=qq->next;
    }
    if(qq==pp && qq!=NULL)
        return 1;
    return 0;
}


int main()
{
    int a[6]={1,2,3,4,5,6};
    Lnode *head=createLinkListByHead(a,6);
    Lnode *resultBeforeSwap=head->next;
    while(resultBeforeSwap!=NULL)
    {
        printf("%3d",resultBeforeSwap->data);
        resultBeforeSwap=resultBeforeSwap->next;
    }
    printf("\n");
    swapList(head);
    Lnode* result=head->next;
    while(result!=NULL)
    {
        printf("%3d",result->data);
        result=result->next;
    }
    printf("\n");

    swapListByK(head,3);
    Lnode* result2=head->next;
    while(result2!=NULL)
    {
        printf("%3d",result2->data);
        result2=result2->next;
    }

    return 0;
}

还有链表的各种排序补充。。。

以上是单链表常见的操作,抛砖引玉,未完待续。。。

posted @ 2013-10-27 21:59  楠楠IT  阅读(280)  评论(0编辑  收藏  举报