数据结构之链表操作

      面试中单链表的相关操作也是常考的内容,本博文也是之前学习时的笔记,在此记录下来,以便日后用到,同时欢迎批评指正。

      一、基本操作 

      单链表的基本操作包括链表的创建、销毁、判空、索引、插入、删除等,下面是在链表的相关操作程序,链表的定义如下:

      typedef struct LNode{  

int data;

struct LNode *next;

}LNode,*LinkList;

此链表是带有头结点的,因此空链表的形式是 head->next=NULL .

       1. 链表的初始化

LinkList InitList(void)    

{
    LinkList head = NULL;
    head = (LinkList)malloc(sizeof(LNode));
    
    head->data = 0;
    head->next = NULL;    
    return head;    

} 

        2.链表的销毁

 void DestoryList(LinkList L)        

{
    LinkList pTemp = L->next,
        qTemp=L->next;
    if (L->next==NULL)                //此为空链表不需要再删除
        {
            printf("the list has already be empty!\n");
        }
     else{
           while(pTemp)
            {
                qTemp = pTemp->next;
                free(pTemp);
                pTemp = qTemp;
            }
            L->next = pTemp;
        }
    }

        3.链表的判空

 bool ListEmpty(LinkList L)

{
    if(L->next == NULL)
        {
            return TRUE;
        }
        else return FALSE;
}    

        4.链表的长度

int ListLength(LinkList L)                

    LinkList pTemp = L->next;
    int NodeCount = 0;
    for(;pTemp;pTemp = pTemp->next)
    {
        NodeCount++;
    }
    return NodeCount;

} 

         5.链表的索引

int GetElem(LinkList L,int i,int* e)        
{                                //取出第i个节点
    LinkList pTemp = L;
    int j = 0;
    while(pTemp && j<i)
    {
        pTemp = pTemp->next;
        j++;
    }
    if(!pTemp || j>i)
        {
            printf("GetElem Error!\n");
            exit(0);
        }
    *e = pTemp->data;
return *e;    

} 

         6.链表的插入

void Insert(LinkList L,int i,int e)
{                                //在第i个节点插入e,因此需要找到第i-1节点,然后在其后插入
    LinkList Ins,
            pTemp = L;
    int j = 0;
    while(pTemp && j<i-1)
    {
        pTemp = pTemp->next;
        j++;
    }
    if(!pTemp || j>i-1)
        {
         printf("Error!\n");
         exit(0);
    }
    Ins = (LinkList)malloc(sizeof(LNode));
    if(Ins==NULL) printf("allocate memory error!\n");
    Ins->data = e;
    Ins->next = pTemp->next;
    pTemp->next = Ins;            

} 

        7.链表的删除

void Delete(LinkList L,int i,int e)
{                                //删除第i个节点,因此找到第i-1节点,然后删除其后的节点
    LinkList Del,
            pTemp = L;
    int j = 0;
    while(pTemp->next && j<i-1)
    {
        pTemp = pTemp->next;
        j++;
    }
    if(!(pTemp->next) || j>i-1
        {
                printf("error!\n");
                exit(0);
        }    
    Del = pTemp->next;
    pTemp->next = Del->next;
    e = Del->data;
    free(Del);

}

        8. 链表的创建

该操作有两种方法,一种是头插法,另一种是尾插法

void CreateList(LinkList &L,int n)

{    //头插法,每次都是在链表的头部插入元素
    L = (LinkList)malloc(sizeof(LNode));
    if(L == NULL)
        {
            printf("error!");
            exit(0);
        }
    L->next=NULL;
    for( i=0;i<n;i++)
    {
        p = (LinkList)malloc(sizeof(LNode));
        scanf(&p->data);
        p->next=L->next;
        L->next = p;
    }

} 

 

void CreateList(LinkList &L,int n)
{  //尾插法,每次都是从链表的尾部插入元素,最后把链表的next指针赋值为NULL
    L = (LinkList)malloc(sizeof(LNode));
    if (L == NULL) 
    {
        printf("error!");
        exit(0);
    }
    L->next = NULL;
    pre = L;
    for(i=0;i<n;i++)
    {
        p = (LinkList)malloc(sizeof(LNode));
        scanf(&p->data);
        pre ->next = p;
        pre = p;
    }
    pre->next = NULL;

} 

         二、其他操作

        1.链表的反转

ListList ReverseList(LinkList L )

{  //带有头结点,p为L的第一个元素
    LinkList p = L->next;
    LinkList prev = NULL,temp = NULL;
    while(p!=NULL)
    {
        temp = p;
        p = p->next;
        temp->next = prev;
        prev = temp;
    }
    L->next = prev;
    return L;

} 

链表的反转也可以使用递归来做! 

2.删除一个元素x

ListList ReverseList(LinkList L )
{  //带有头结点,p为L的第一个元素
    LinkList p = L->next;
    LinkList prev = NULL,temp = NULL;
    while(p!=NULL)
    {
        temp = p;
        p = p->next;
        temp->next = prev;
        prev = temp;
    }
    L->next = prev;
    return L;

} 

3.删除所有重复的元素

 void DeleteAllX(LinkList L)

{
    LinkList p = L,
             pPrev,
             pCurr;
    while( p!= NULL)
    {
        pPrev = p;
        pCurr = p->next;
        while(pCurr != NULL)
        {
            if(pCurr->data == p->data)
                {
                    pPrev->next = pCurr->next;
                    free(pCurr);
                    pCurr = pPrev->next;
                }
            else
                {
                    pPrev = pCurr;
                    pCurr = pCurr->next;
                }
        }
        p = p->next;
    }
}

  4.判断链表是不是有环

Bool IsLoop(LinkList head)
{
    LinkList slow = head,
                     fast = head;
    while(fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if(slow == fast)
            break;
    }
    return !(fast == NULL || fast->next == NULL);

} 

  如果链表带环的话,找出环的入口,这个原理网上有介绍,算法也一大堆!

  5.将链表分为两个链表,一个为奇数序的元素,另一个为偶数序的元素

void splice(LinkList La, LinkList Lb)
{
    LinkList Lb,pb,pa,pTemp;
    Lb = (LinkList)malloc(sizeof(LNode));
    pa = La->next;
    pb = Lb;
    while(pa->next)
    {
        pTemp = pa->next;
        pa->next = pTemp->next;
        pb->next = pTemp;
        pb = pTemp;
        pa = pa->next;
    }
    pb->next = NULL;

} 

  6.单链表的插入排序

void InsertSort(LinkList L)
{
    LinkList p,q,pre,r;
    
    p = L->next;
    while(p->next)
    {
        q = p->next;
        if(q->data < p->data)
            {
                pre = L;
                r = L->next;
                while(r!=p && r->data < q->data)
                {
                    pre = r;
                    r = r->next;
                }
              p->next = q->next;
              q->next = r;
              pre->next = q;
            }
        else
            p = p->next;
    }

} 

  7.单链表的选择排序

 void SelectSort(LinkList L)

//r总是指向最小的节点
    LinkList p,q,r;
    p = L->next;
    while(p->next)
    {
        r = p;
        q = p->next;
        while(q)
        {
            if(r->data > q->data)
                 r = q;
            q = q->next;
        }
        if(r != p)
            {
                temp = p->data;
                p->data = r->data;
                r->data = temp;
            }
        p = p->next;
    }
}

 

posted on 2013-03-20 00:38  糊涂先生  阅读(317)  评论(0编辑  收藏  举报