数据结构-单链表
本文内容
- 初始化单链表-带头节点
- 自动创建单链表-逆序
- 自动创建单链表-顺序
- 手动创建单链表-输入
- 自动创建单链表-数组
- 创建交叉的单链表
- 创建带环的单链表
- 将一般的单链表转换成循环单链表
- 将循环单链表转换成一般的单链表
- 销毁单链表
- 单链表长度
- 带环的单链表长度
- 在单链表第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 等等。