数据结构-单链表

本文内容

  • 初始化单链表-带头节点
  • 自动创建单链表-逆序
  • 自动创建单链表-顺序
  • 手动创建单链表-输入
  • 自动创建单链表-数组
  • 创建交叉的单链表
  • 创建带环的单链表
  • 将一般的单链表转换成循环单链表
  • 将循环单链表转换成一般的单链表
  • 销毁单链表
  • 单链表长度
  • 带环的单链表长度
  • 在单链表第i个位置插入元素e
  • 删除单链表第i个元素
  • 合并单链表
  • 单链表置逆
  • 单链表排序
  • 单链表是否包含环
  • 单链表是否为循环单链表
  • 获得单链表第i个节点元素
  • 获得元素为e的节点位置
  • 获得单链表的中间节点元素
  • 查找单链表元素为e的指针
  • 查找单链表倒数第K个节点的元素
  • 查找交叉的单链表的交叉节点
  • 查找带环的单链表的环入口节点
  • 输出单链表,不输出头节点
  • 输出单链表,输出头节点
  • 输出带环的单链表

 

linklist.h 声明文件

typedef int ElementType;
 
#ifndef LIST_H_INCLUDED
#define LIST_H_INCLUDED
 
struct LNode;
typedef struct LNode *linkList;
typedef linkList LinkList;
typedef linkList LinkPos;
 
/* 初始化-创建头节点 */
LinkList InitList_L();
/* 自动创建-逆序 */
LinkList CreateAutoList_L01( int length );
/* 自动创建-顺序 */
LinkList CreateAutoList_L02( int length );
/* 手动创建-输入 */
LinkList CreateHandList_L( int length );
/* 自动创建-数组 */
LinkList CreateHandArrList_L( int a[], int length );
/* 创建交叉单链表 */
void CreateIntersectantList_L( LinkList La, LinkList Lb, int index);
/* 创建带环的单链表 */
LinkList CreateLoopList_L( LinkList La, LinkList Lb, int index);
/* 将一般的单链表转换成循环单链表 */
void ConvertCircularList_L( LinkList L );
/* 将循环单链表转换成一般的单链表 */
void ConvertGeneralList_L( LinkList L );
/* 销毁单链表 */
void DestroyList_L( LinkList L );
 
/* 单链表长度 */
int LengthList_L( LinkList L );
/* 带环的单链表长度 */
int LengthLoopList_L( LinkList L );
/* 在单链表第i个位置插入元素e */
void InsertList_L( LinkList L, int index, ElementType e );
/* 删除单链表第i个元素 */
void DeleteList_L( LinkList L, int index, ElementType *e );
/* 合并单链表 */
void MergeList_L( LinkList La, LinkList Lb );
/* 单链表置逆 */
void ReverseList_L01( LinkList L );
void ReverseList_L02( LinkPos pHead, LinkPos pTail);
/* 单链表排序 */
void SortList_L( LinkList L );
/* 单链表是否包含环 */
int IsLoopList_L( LinkList L );
/* 单链表是否为循环单链表 */
int IsCircularList_L( LinkList L );
 
/* 获得单链表第i个节点元素 */
ElementType GetList_L( LinkList L, int i );
/* 获得元素为e的节点位置 */
int LocateList_L( LinkList L, ElementType e );
 
/* 获得单链表中间节点元素 */
ElementType FindMiddleList_L( LinkList L );
/* 查找单链表元素为e的指针 */
LinkPos FindList_L( LinkList L, ElementType e );
/* 查找单链表倒数第K个节点的元素 */
ElementType FindKthList_L( LinkList L, int KthIndex );
/* 查找交叉链表交叉节点 */
ElementType FindIntersectantList_L( LinkList La, LinkList Lb, int testIndex );
/* 查找环入口节点 */
ElementType FindLoopList_L( LinkList L );
 
/* 输出单链表,不输出头节点 */
void PrintList_L( LinkList L);
/* 输出单链表,输出头节点 */
void PrintAllList_L( LinkList L );
/* 输出带环的单链表 */
void PrintLoopList_L( LinkList L );
 
#endif


linklist.c 实现文件

#include "linklist.h"
#include <stdio.h>
#include <stdlib.h>
 
struct LNode
{
    ElementType Element;
    linkList    Next;
};
/* 初始化 */
LinkList InitList_L()
{
    LinkList L = (linkList)malloc( sizeof( struct LNode ) );
    L->Element = -1;
    L->Next = NULL;
    return L;
}
/* 自动创建-逆序 */
LinkList CreateAutoList_L01( int length )
{
    int i;
    LinkPos n;
 
    LinkList L = InitList_L();
    for(i=1 ; i<=length ; i++)
    {
        n = (linkList)malloc( sizeof( struct LNode ) );
        n->Element = i + 1000;
        n->Next = L->Next;
        L->Next = n;
    }
    return L;
}
/* 自动创建-顺序 */
LinkList CreateAutoList_L02( int length )
{
    int i;
    LinkPos n, p;
 
    LinkList L = InitList_L();
    p = L;
    for(i=1 ; i<=length ; i++)
    {
        n = (linkList)malloc( sizeof( struct LNode ) );
        n->Element = i + 2000;
        p->Next = n;
        p = n;
    }
    p->Next = NULL;
    return L;
}
/* 手动创建-输入 */
LinkList CreateHandList_L( int length )
{
    int i;
    LinkPos n;
 
    LinkList L = InitList_L();
    for(i=length ; i>0 ; --i)
    {
        n = (linkList)malloc( sizeof( struct LNode ) );
        scanf("%d",& n->Element);
        n->Next = L->Next;
        L->Next = n;
    }
    return L;
}
/* 自动创建-数组 */
LinkList CreateHandArrList_L( int a[], int length )
{
    int i;
    LinkList L;
    LinkPos p;
 
    L = InitList_L();
    for(i=length-1 ; i>=0 ; --i)
    {
        p = (linkList)malloc( sizeof( struct LNode ) );
        p->Element = a[i];
        p->Next = L->Next;
        L->Next = p;
    }
    return L;
}
/* 创建交叉链表 */
/* index: {1, LengthList_L} */
void CreateIntersectantList_L( LinkList La, LinkList Lb, int index)
{
    LinkPos pa, pb;
    int count = 0;
 
    pa = La;
    pb = Lb;
    while( pa->Next && count<index )
    {
        pa = pa->Next;
        count++;
    }
    while( pb->Next ) pb = pb->Next;
    pb->Next = pa;
}
/* 创建带环的单链表 */
/* index: {1, LengthList_L} */
LinkList CreateLoopList_L( LinkList La, LinkList Lb, int index)
{
    LinkPos pa, pb;
    int count = 0;
    pa = La;
    pb = Lb;
    // 交叉单链表
    while( pa->Next && count<index )
    {
        pa = pa->Next;
        count++;
    }
    while( pb->Next ) pb = pb->Next;
    pb->Next = pa;
    // 环单链表
    while( pa->Next) pa = pa->Next;
    pa->Next = Lb->Next;
    return La;
}
/* 一般单链表转换成循环单链表 */
void ConvertCircularList_L( LinkList L )
{
    LinkPos p;
    p = L;
    while( p->Next ) p = p->Next;
    p->Next = L;
}
/* 循环单链表转换成一般单链表 */
void ConvertGeneralList_L( LinkList L )
{
    LinkPos p;
 
    p = L;
    while( p->Next != L ) p = p->Next;
    if( p->Next == L ) p->Next = NULL;
}
/* 销毁单链表 */
void DestroyList_L( linkList L )
{
    LinkPos P, q;
 
    P = L->Next;
    L->Next = NULL;
    while( P != NULL )
    {
        q = P->Next;
        free( P );
        P = q;
    }
    free(L);
}
/* 单链表长度 */
int LengthList_L( LinkList L )
{
    int len = 0;
    LinkPos p;
 
    p = L->Next;
    while( p )
    {
        len++;
        p = p->Next;
    }
    return len;
}
/* 包含环的单链表的长度 */
int LengthLoopList_L( LinkList L )
{
    LinkPos f, s;
    int count=0;
 
    f = L;
    s = L;
    while( f && f->Next )
    {
        s = s->Next;
        f = f->Next->Next;
        count++;
        if( s==f ) break;
    }
    if( !f || !f->Next ) return count;
    s = L;
    while( s != f )
    {
        s = s->Next;
        f = f->Next;
        count++;
    }
    return count;
}
/* 插入 */
/* index:{ 0, Length(L)+1 } */
void InsertList_L( LinkList L, int index, ElementType e )
{
    int j = 0;
    LinkPos p, n;
 
    p = L;
    // p->Next && j < index-1 这个条件当index为 Length(L)+1 时,不能插入链表尾
    while( p && j < index-1 ) {
        p = p->Next;
        j++;
    }
    if( p && j <= index ) // p->Next && j <= index
    {
        n = (linkList)malloc( sizeof(struct LNode) );
        n->Element = e;
        n->Next = p->Next;
        p->Next = n;
    }
}
/* 删除 */
/* index: { 1, Length(L) }*/
void DeleteList_L( LinkList L, int index, ElementType *e )
{
    int j = 0;
    LinkPos p, q;
 
    p = L;
    while( p->Next && j < index-1 )
    {
        p = p->Next;
        j++;
    }
    if( p->Next && j <=index )
    {
        *e = p->Next->Element;
        q = p->Next;
        p->Next = q->Next;
        free( q );
    }
}
/* 合并 */
void MergeList_L( LinkList La, LinkList Lb )
{
    LinkPos pa, pb, pc;
    pa = La->Next;
    pb = Lb->Next;
    pc = La;
    while( pa && pb )
    {
        if( pa->Element <= pb->Element)
        {
            pc->Next = pa;
            pc = pa;
            pa = pa->Next;
        }
        else
        {
            pc->Next = pb;
            pc = pb;
            pb = pb->Next;
        }
    }
    pc->Next = pa ? pa : pb;
    free( Lb );
}
/* 置逆 */
void ReverseList_L01( LinkList L )
{
    LinkPos p, q, r;
 
    p = L;
    q = p->Next;
    while( q )
    {
        r = q->Next;
        q->Next = p;
        p = q;
        q = r;
    }
    L->Next->Next = NULL;
    L->Next = p;
}
void ReverseList_L02( LinkPos pHead, LinkPos pTail)
{
    LinkPos p;
 
    if (pHead == NULL || pHead->Next == NULL) return;
    // Address pTail->Next as a temp pointer
    // Since it should NULL all the times
    pTail->Next = pHead;
    p = pHead->Next;
    // Don't need worry about the cleanup things on the next pointer of pFirst
    while( p != pTail )
    {
        // Address pHead->Next as a temp pointer
        // Since it will be useless after the first iteration
        pHead->Next = p->Next;
        // pTail->Next has pointed to pHead
        p->Next = pTail->Next;
        pTail->Next = p;
        p = pHead->Next;
    }
    pHead->Next = NULL;
}
/* 排序 */
void SortList_L( LinkList L )
{
    LinkPos p, q, r, s;
 
    LinkList Lt = InitList_L();
    p = Lt;
    p->Next = L;
    while( p->Next )
    {
        q = p->Next;
        r = p;
        while( q->Next )
        {
            if( q->Next->Element < r->Next->Element ) r = q;
            q = q->Next;
        }
        if( r != p )
        {
            s = r->Next;
            r->Next = p->Next;
            r = s->Next;
            s->Next = p->Next->Next;
            p->Next->Next = r;
            p->Next = s;
        }
        p = p->Next;
    }
    L = Lt->Next;
    free( Lt );
}
/* 是否存在环 */
int IsLoopList_L( LinkList L )
{
    LinkPos f, s;
 
    f = L->Next;
    s = L;
    while( f && f != s )
    {
        f = f->Next->Next;
        s = s->Next;
    }
    if( !f ) return 0;
    else return 1;
}
/* 是否为循环单链表 */
int IsCircularList_L( LinkList L )
{
    LinkPos p;
 
    p = L;
    while( p->Next && p->Next!=L ) p = p->Next;
    if( !p->Next ) return 0;
    else return 1;
}
/* 查找第i个节点 */
/* index: { 1, LengthList_L() }*/
ElementType GetList_L( LinkList L, int index )
{
    int count = 0;
    LinkPos p;
 
    p = L;
    while( p && count<index )
    {
        p = p->Next;
        count++;
    }
    if( !p )
        return -1;
    else
        return p->Element;
}
/* 查找X节点的索引 */
int LocateList_L( LinkList L, ElementType e )
{
    int index = 1;
    LinkPos p;
 
    p = L->Next;
    while( p && p->Element==e )
    {
        p = p->Next;
        index++;
    }
    if(p == NULL) return 0;
    else return index;
}
/* 查找中间节点 */
/* 思想:一个指针每次走一步,另一个指针每次走两步 */
/* 若LengthList_L为奇数,则返回中间节点,否则返回中间两个节点的前一个 */
ElementType FindMiddleList_L( LinkList L )
{
    LinkPos p, q;
    p = L;
    q = L;
    while( p )
    {
        p = p->Next;
        if( !p->Next )
        {
            q = q->Next;
            break;
        }
 
        p = p->Next;
        if( !p->Next )
        {
            break;
        }
        q = q->Next;
    }
    return q->Element;
}
/* 查找X节点 */
LinkPos FindList_L( LinkList L, ElementType e )  
{  
    LinkPos P;  
  
    P = L->Next;  
    while( P && P->Element!=e ) P = P->Next;  
    return P;  
} 
/* 查找倒数第K个节点 */
/* KthIndex: { 1, LengthList_L() }*/
ElementType FindKthList_L(LinkList L, int KthIndex)
{
    LinkPos p, q;
    int i = 0;
    p = L;
    q = L;
    while( p && i!=KthIndex )
    {
        p = p->Next;
        i++;
    }
    while( p )
    {
        p = p->Next;
        q = q->Next;
    }
    return q->Element;
}
/* 查找交叉链表交叉节点 */
ElementType FindIntersectantList_L( LinkList La, LinkList Lb, int testIndex )
{
    LinkList pa, pb;
    ElementType e;
 
    pa = La;
    pb = Lb;
    CreateLoopList_L(pa, pb, testIndex);
    e = FindLoopList_L(pa);
 
    pb = Lb->Next;
    while( pb->Next != Lb->Next ) pb = pb->Next;
    pb->Next = NULL;
    return e;
}
/* 查找环入口节点 */
ElementType FindLoopList_L( LinkList L )
{
    LinkPos s, f;
 
    s = L;
    f = L;
    while( f && f->Next )
    {
        s = s->Next;
        f = f->Next->Next;
        if( s == f ) break;
    }
    if( !f || !f->Next ) return -1;
    s = L;
    while( s!=f )
    {
        s = s->Next;
        f = f->Next;
    }
    return s->Element;
}
/* 输出单链表,不输出头节点 */
void PrintList_L( LinkList L )
{
    LinkPos p;
    int index = 0;
 
    p = L->Next;
    printf("LENGTH %d, PRINT linkList.../n", LengthList_L(L));
    while( p )
    {
        printf("INDEX = %3d, VALUE = %4d/n", ++index, p->Element);
        p = p->Next;
    }
    printf("END./n/n");
}
/* 输出单链表,输出头节点 */
void PrintAllList_L( LinkList L )
{
    LinkPos p;
    int index;
 
    index = 0;
    p = L;
    printf("LENGTH %d, PRINT linkList.../n", LengthList_L(L));
    while( p )
    {
        printf("INDEX = %3d, VALUE = %4d/n", index++, p->Element);
        p = p->Next;
    }
    printf("END./n/n");
}
/* 输出带环的单链表 */
void PrintLoopList_L( LinkList L )
{
    LinkPos f, s;
 
    f = L;
    s = L;
    while( f && f->Next )
    {
        printf("slow VALUE = %4d, fast VALUE = %4d/n", s->Element, f->Element);
        s = s->Next;
        f = f->Next->Next;
        if( s == f ) break;
    }
    if( !f || !f->Next ) return;
    s = L;
    while( s != f )
    {
        printf("slow VALUE = %4d, fast VALUE = %4d/n", s->Element, f->Element);
        s = s->Next;
        f = f->Next;
    }
    printf("s point value=%d, f point value=%d/n", s->Element, f->Element);
    printf("END./n/n");
}

 

自己写个入口函数main函数调用一下,比如,创建 CreateAutoList_L01 一个单链表 CreateAutoList_L01,再销毁 DestoryList_L 它;创建 CreateIntersectantList_L 一个交叉单链表,然后查找 FindIntersectantList_L 交叉节点;创建 CreateLoopList_L 一个带环的单链表,然后判断单链表是否包含环 IsLoopList_L,并查找环的入口节点 FindLoopList_L 等等。

 

下载 Demo

posted @ 2011-08-30 22:03  船长&CAP  阅读(578)  评论(0编辑  收藏  举报
免费流量统计软件