首页 > 代码库 > 数据结构(二)线性表——链表

数据结构(二)线性表——链表

通常情况下,链接可分为单链表、双向链表和循环链表三种常用类型。

一、单链表基本操作的实现

使用链式存储结构来实现的线性表称为链表。首元结点、头结点、头指针、空指针。

1.单链表的类型定义

typedef struct LNode//结点类型 
{
    LElemType data;//数据域 
    struct LNode * next;//指针域 
} LNode, * LinkList;

2.初始化操作InitLinkList(&L)

Status InitLinkList(LinkList &L)
{
    //创建空的带头结点的单链表L
    L=(LinkList)malloc(sizeof(LNode));//申请头结点 
    if(!F) return OVERFLOW;//若失败 
    L->next=NULL;//头结点的后继指针域赋为NULL 
    return OK; 
} 

3.求表长操作listLength(&L)

int listLength(LinkList L)
{
    LNode *p=L;//p指向头结点 
    int j=0;
    while(p->next)//当存在 
    {
        p=p->next;//指针后移,指向后继 
        j++;
    }
    return j;//返回计数器 
} 

4.取元素操作getElem(LinkList L,int i,LElemType &e)

Status getElem(LinkList L,int i,LElemType &e)
{
    LNode *p=L;
    int j=0;
    while(j<i&&p->next)//不为i结点,且不为最后一个 
    {
        p=p->next;//向后查找 
        j++;
    } 
    if(j==i)//若找到 
    {
        e=p->data;//由e返回其值 
        return OK; 
    } 
    else return ERROR;//若没找到,返回ERROR 
} 

5.按值查找locateElem(L,e)

LinkList locateElem(LinkList L,LElemType e)
{
    LNode *p=L->next;//p指向第一个结点 
    while(p&&!equal(p->data,e))//若不等于e 
        p=p->next;//向后查找 
    if(p) return p;//找到 
    else return NULL;//没找到 
} 

6.插入操作listInsert(&L,i,e)

Status listInsert(LinkList &L,int i,LElemType e)
{
    //在单链表L的第i个位置插入一个值为e的结点
    LNode *p=L,*q;//q用于指向想要插入的结点 
    int j=0;
    while(j<i-1&&p->next)
    {
        p=p->next;
        j++;
    } 
    if(j==i-1)//在j后插入新结点 
    {
        q=(LNode *)malloc(sizeof(LNode));//生成新结点
        if(!q) return OVERFLOW;
        q->data=http://www.mamicode.com/e;
        q->next=p->next;
        p->next=q;
        return OK; 
    }
    else return ERROR;
} 

7.删除操作listDelete(&L,i,&e)

Status listDelete(LinkList &L,int i,LElemType &e)
{
    LNode *p=L,*q;
    int j=0;
    while(j<i-1&&p->next)
    {
        p=p->next;
        j++; 
    }
    if(j==i-1&&p->next)//判断i结点是否存在 
    {
        q=p->next;
        p->next=q->next;
        e=q->data;//由e返回删除元素的值 
        free(q);
    } 
    else return ERROR; 
} 

8.头插法建立单链表操作createList(&L,n)

void createList(LinkList &L,int n)
{
    //依次读入n个元素,建立单链表L 
    LNode *p;
    int i;
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    for(i=1;i<=n;i++)
    {
        p=(LNode *)malloc(sizeof(LNode));//生成p结点
        inputListElem(p->data);//调用元素读入函数 
        p->next=L->next;
        L->next=P; 
    }
}

9.尾插法建立单链表操作createList(&L,n)

void createList(LinkList &L,int n)
{
    //依次读入n个元素,建立单链表L 
    LNode *p,*r;
    int i;
    L=(LinkList)malloc(sizeof(LNode));//生成头结点 
    r=L;//尾指针r指向头结点 
    for(i=1;i<=n;i++)
    {
        p=(LNode *)malloc(sizeof(LNode));//生成p结点
        inputListElem(p->data);//调用元素读入函数,读入p结点的值 
        r->next=p;//把p结点放到r结点后,尾 
        r=p; //重置r 
    }
    r->next=NULL; //最后一个结点后继指针为空 
}

二、单链表实例——约瑟夫环问题

1.问题描述:

设编号为1、2、3...、n的n个人围坐一圈,约定从编号为k(1=<k=<n)的人开始从1报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的人出列,以此类推,直到所有人都出列为止,由此产生一个编号序列。

2.算法描述:

数据结构(二)线性表——链表