单链表相关问题

先定义一个单链表结构体:

typedef int DataType;
typedef struct _list 
{
    DataType data;
    struct _list *next;
}List,*PList;


相关操作:

1,几个基本操作

PList InsHead(PList *head,DataType x)  //在头部插人
{
    PList newNode = (List *)malloc(sizeof(List));    //直接插入
    newNode->data = x;
    newNode->next = *head;
    *head = newNode;  
    return *head;
}

PList InsEnd(PList *head,DataType x)  //在尾部插入
{
    PList newNode= (List *)malloc(sizeof(List)); 
    if (*head == NULL)
    {
        newNode->data = x;
        newNode->next = NULL;
        *head = newNode;
    }
    else
    {
        PList workNode = *head;
        while(workNode->next != NULL)   //先找到尾部
        {
            workNode = workNode->next;
        }
        workNode->next = newNode;
        newNode->data = x;
        newNode->next = NULL;
    }
    return *head;
}
void PrintList(PList *head) //输出链表元素 { PList workNode = *head; while (workNode != NULL) { printf("%d—>",workNode->data); workNode = workNode->next; } printf("NULL"); printf("\n"); } PList EndOfList(PList *head) //找到链表的尾节点 { PList workNode = *head; while (workNode->next != NULL) { workNode = workNode->next; } return workNode; } int LenOfList(PList *head) //返回链表的长度 { int len = 0; PList workNode = *head; while (workNode != NULL) { len++; workNode = workNode->next; } return len; }

 2,链表相交

  如果两个链表相交,则它们的尾节点一定是指向同一地址。

int IsInsect(PList *List1,PList *List2)  //判断两个链表是否相交
{
    PList workNode1 = EndOfList(List1);
    PList workNode2 = EndOfList(List2);
    
    if (workNode1 == workNode2)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}

PList InsectNode(PList *List1,PList *List2)  //返回链表的交点
{
    PList RetNode = NULL;
    if (IsInsect(List1,List2))
    {
        PList workNode1 = *List1;
        PList workNode2 = *List2;
        
        int len1 = LenOfList(&workNode1);
        int len2 = LenOfList(&workNode2);
        int len = len1 - len2;
        
        if (len > 0)   //让两链表在同一起跑线,然后再往后找
        {
            for (int j = 0; j < len; j++)
            {
                workNode1 = workNode1->next;
            }
        }
        else
        {
            len = abs(len);
            for (int j = 0; j < len; j++)
            {
                workNode2 = workNode2->next;
            }
        }
        while(workNode1 != workNode2)
        {
            workNode1 = workNode1->next;
            workNode2 = workNode2->next;
        }
        RetNode = workNode1;
    }
    return RetNode;
}

int LenOfInsect(PList *List1,PList *List2)  //链表相交部分的长度
{
    if (IsInsect(List1,List2))
    {
        int i = 0;
        PList workNode1 = *List1;
        PList workNode2 = *List2;
        
        int len1 = LenOfList(&workNode1);
        int len2 = LenOfList(&workNode2);
        int len = len1 - len2;
        
        if (len > 0)
        {
            for (int j = 0; j < len; j++)
            {
                workNode1 = workNode1->next;
            }
        }
        else
        {
            len = abs(len);
            for (int j = 0; j < len; j++)
            {
                workNode2 = workNode2->next;
            }
        }
        while(workNode1 != workNode2)
        {
            workNode1 = workNode1->next;
            workNode2 = workNode2->next;
        }
        while(workNode1 != NULL)
        {
            i++;
            workNode1 = workNode1->next;
        }
        return i;
    }
    else
    {
        return 0;
    }
}

3,链表是否成环
  先定义一个结构体,用来记录链表是否有环,及环中的某个节点。

typedef struct _Ret
{
    PList Node;
    int ret;
}Ret,*PRet;
PRet IsCycleList(PList *head)  //链表是否成环
{
       PRet RetSruct = (PRet)malloc(sizeof(Ret));
    PList workNode1 = *head;
    PList workNode2 = workNode1;
    
    while (workNode1->next&&workNode2->next->next)
    {
        workNode1 = workNode1->next;
        workNode2 = workNode2->next->next;
        if (workNode1 == workNode2)  //如果成环,一个走1步,一个走2步,它们必定能碰到一起
        {
            RetSruct->Node = workNode1;
            RetSruct->ret = 1;
            return RetSruct;
        }        
    }
    return NULL;
}

int LenOfCycle(PList *head)
{
    if ((IsCycleList(head))->ret)
    {
        int i = 0;
        PList Node = (IsCycleList(head))->Node;
        PList workNode = Node;
        while (workNode->next != Node)
        {
            i++;
            workNode = workNode->next;
        }
        i++;  //从这个节点起再次访问到这个节点,即为环的长度
        return i;
    }
    return 0;
}

PList NodeOfCycle(PList *head)
{
    if ((IsCycleList(head))->ret)
    {
       PList Node = (IsCycleList(head))->Node;  //先找到环内一个节点
       PList ReNode = Node->next;   //下一个节点
       PList RetNode = NULL;       

       Node->next = NULL;        //从环的某个节点处断开,转换成2个相交链表
       RetNode = InsectNode(head,&ReNode);

       Node->next = ReNode;     //还原链表
       return RetNode;
    }
    return NULL;
}

 

posted @ 2013-09-17 22:14  dingsd  阅读(261)  评论(1)    收藏  举报