设立尾指针的单循环链表的表示和实现

设有尾指针的单循环链表的12个基本操作

void InitList(LinkList &L){
    L = (LinkList)malloc(sizeof(LNode));//产生头结点,并使L指向此头结点
    if (!L)exit(OVERFLOW);
    L->next = L;//头结点的指针域指向头结点
}

void ClearList(LinkList &L){
    LinkList p, q;
    L = L->next;//L指向头结点
    p = L->next;//p指向第一个结点
    while (p != L){//未到表尾
        q = p->next;//q指向p的后继结点
        free(p);//释放p所指结点
        p = q;//p指向q所指结点
    }
    L->next = L;//头结点指针域指向自身(头结点)
}

void DestroyList(LinkList &L){
    ClearList(L);
    free(L);
    L = NULL;
}

Status ListEmpty(LinkList L){
    if (L->next == L)return TRUE;
    else return FALSE;
}

int ListLength(LinkList L){
    LinkList p = L->next;//p指向头结点
    int i = 0;
    while (p != L)//未到表尾
    {
        i++;//计数器+1
        p = p->next;//p指向下一个结点
    }
    return i;
}

Status GetElem(LinkList L, int i, ElemType &e){
    int j = 1;//初始化,j为计数器,初值为1
    LinkList p = L->next->next;//p指向第1个结点
    if (i <= 0 || i > ListLength)return ERROR;//第i个元素不存在
    while (j < i)//顺时针向后查找,直到p指向第i个元素
    {
        j++;//计数器+1
        p = p->next;//p指向下一个结点
    }
    e = p->data;//第i个元素赋给e
    return OK;
}

int LocateElem(LinkList L, ElemType e, Status(*compare)(ElemType, ElemType)){
    int i = 0;//计数器初值为0
    LinkList p = L->next->next;//p指向第1个结点
    while (p!=L->next)//p未指向头结点
    {
        i++;
        if (compare(p->data, e))//找到这样的数据元素
            return i;//返回其位序
        p = p->next;//p指向下一个结点
    }
    return 0;//满足关系的数据元素不存在
}

Status PriorElem(LinkList L, ElemType cur_e, ElemType &pre_e){
    LinkList q, p = L->next->next;//p指向第1个结点
    q = p->next;//q指向p的后继
    while (q != L->next){//p未到表尾(q未指向头结点)
        if (q->data == cur_e){//p的后继为cur_e
            pre_e = p->data;//将p所指的元素的值赋给pre_e
            return OK;
        }
        p = q;//p的后继不为cur_e,p向后移
        q = q->next;//q指向p的后继
    }
    return ERROR;
}

Status NextElem(LinkList L, ElemType cur_e, ElemType &next_e){
    LinkList p = L->next->next;//p指向第1个结点
    while (p!=L){//p未到表尾
        if (p->data == cur_e){//p所指结点的值为cur_e
            next_e = p->next->data;//将p所指结点的后继结点的值赋给next_e
            return OK;
        }
        p = p->next;//p指向下一个结点
    }
    return ERROR;
}

Status ListInsert(LinkList L, int i, ElemType e){
    int j = 0;
    LinkList s, p = L->next;//p指向头结点
    if (i <= 0 || i > ListLength(L) + 1) return ERROR;
    while (j < i - 1)//寻找第i-1个结点
    {
        j++;
        p = p->next;//p指向下一个结点
    }
    s = (LinkList)malloc(sizeof(LNode));//生成新结点,以下将其插入L中
    s->data = e;
    s->next = p->next;//新结点指向原第i个结点
    p->next = s;//原第i-1个结点指向新结点
    if (p == L)//插在表尾
        L = s;//L指向新的尾结点
    return OK;
}

Status ListDelete(LinkList L, int i, ElemType &e){
    int j = 0;
    LinkList q, p = L->next;//p指向头结点
    if (i <= 0 || i >= ListLength(L)) return ERROR;//第i个元素不存在
    while (j < i - 1)//寻找第i-1个结点
    {
        j++;
        p = p->next;//p指向下一个结点
    }
    q = p->next;//q指向待删除结点,p的后继
    p->next = q->next;//待删除结点的前驱指向待删结点的后继
    e = q->data;//将待删结点的值赋给e
    if (L == q)//删除的是表尾元素
        L = p;//L指向新的表尾元素
    free(q);//释放待删除结点
    return OK;
}

void ListTraverse(LinkList L, void(*visit)(ElemType&)){
    LinkList p = L->next->next;//p指向首元结点
    while (p != L->next)//p不指向头结点
    {
        visit(p->data);
        p = p->next;
    }
    printf("\n");
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-30 05:47:12

设立尾指针的单循环链表的表示和实现的相关文章

JAVA单链表的实现-不带头结点但带有尾指针

1,本程序实现了线性表的链式存储结构.实现的链表带有两个指针,一个始终指向链表中的第一个结点,另一个指针始终指向链表中的最后一个结点. 之所以设置尾指针,是因为,在插入元素到链表中的末尾时,可以通过尾指针直接找到链表的最后一个元素,从而不需要遍历链表就可以完成插入操作. 2,具体实现链表的类名为LList2.java,它首先实现了线性表的接口ListInterface,该接口的定义见:http://www.cnblogs.com/hapjin/p/4549492.html LList2.java

双循环链表(包含头指针与尾指针)

双循环链表(包含头指针与尾指针) 以及基本功能的实现 list_ d_link_c.h #ifndef _LIST_D_LINK_C_ #define _LIST_D_LINK_C_ #include<iostream> #include<assert.h> using namespace std; #define ElemType int typedef struct Node { ElemType data; struct Node *prio; struct Node *ne

链表之 头节点与尾指针 区别

单链表的必要条件:头节点的head,以及尾指针指向null: 1 头结点 首先,不要被以下三个词组弄混了: 链表头:数据内容为第一个元素的结点. 头指针:指向头结点元素的指针. 头结点:数据内容无效,其指针是头指针. 一句话描述为:头指针是指向头结点的指针,头结点是指向链表头的结点. 对于一个链表来说,头指针是一定存在的,是访问链表的入口,如果没有头指针则无法对其进行访问:链表头对于非空表来说是一定存在的,非空表则不存在. 2 尾指针 另外一种链表的技巧是使用尾指针. 尾指针是相对于头指针而言的

13输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4250795.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. 题目分析: 1.链表的倒数第0个结点为链表的尾指针,设为r,则r指向最后一

JAVA单链表的实现-不带头结点且没有尾指针

本程序采用JAVA语言实现了线性表的链式实现.首先定义了线性表的接口ListInterface,然后LList类实现了ListInterface完成了链表的实现. 本实现中,链表是不带表头结点的,且有一个指针始终指向链表中的第一个元素,并没有定义尾指针.因此,每次向链表中插入新结点时需要遍历链表一次. 更详细的解释参考<数据结构与算法分析 JAVA语言描述第二版>Frank M. Carrano 著 ListInterface接口的定义如下: public interface ListInte

约瑟夫环 C语言 单循环链表

/*---------约瑟夫环---------*/ /*---------问题描述---------*/ /*编号为1,2,-,n的n个人围坐一圈,每人持一个密码(正整数). 一开始任选一个正整数作为报数上限值m, 从第一个人开始自1开始顺序报数,报到m时停止. 报m的人出列,将他的密码作为新的m值,从他的下一个人开始重新从1报数, 如此下去,直至所有人全部出列为止.试设计一个程序求出列顺序.*/ /*---------问题分析---------*/ /*n个人围坐一圈,且不断有人出列,即频繁

(续)顺序表之单循环链表(C语言实现)

单循环链表和单链表的唯一区别在于单循环链表的最后一个节点的指针域指向第一个节点, 使得整个链表形成一个环. C实现代码如下: #include<stdio.h> typedef struct node { int data; struct node *next; }Node; //链表的初始化 Node* InitList(int number) { int i; Node *pHead=(Node *)malloc(sizeof(Node)); Node *TempHead=pHead; N

【数据结构】两个单循环链表的连接操作

如果在单链表或头指针表示的链表上操作这个比较消耗性能,因为都需要遍历第一个链表,找到an,然后将b1链接到an的后面,时间复杂度是:O(n).若在尾指针表示的单循环链表上实现,则只需改变指针,无需遍历,时间复杂度是:O(1) 现在看算法实现,需要4个主要步骤,都注释了: LinkList Connect(LinkList A,LinkList B){ //假设A,B为非空循环链表的尾指针 LinkList p = A->next;//1.保存A链表的头结点的位置 A->next = B->

单循环链表(C语言实现)

//CList.h //结构体定义以及函数声明 #ifndef CLIST_H #define CLIST_H #include <stdio.h> #include <assert.h> #include <malloc.h> #include <iostream> typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }Node, *PNode; typ