循环链表【尾指针】笔记

#include "stdio.h"    
#include "string.h"
#include "ctype.h"      
#include "stdlib.h"   

#include "math.h"  
#include "time.h"

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */


Status visit(ElemType c)
{
    printf("%d ",c);
    return OK;
}

typedef struct Node
{
    ElemType data;
    struct Node *next;
}Node;
typedef struct Node *LinkList; /* 定义LinkList */

/* 初始化链式线性表 */
Status InitList(LinkList *L) 
{ 
    *L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
    if(!(*L)) /* 存储分配失败 */
        return ERROR;
    (*L)->next=*L;
    return OK;
}

/* 初始条件:链式线性表L已存在。操作结果:若L为空表,则返回TRUE,否则返回FALSE */
Status ListEmpty(LinkList rear)
{ 
    if(rear->next == rear)/*一定要注意“==”和“=”的区别*/
        return TRUE;
    else
        return FALSE;
}



/* 初始条件:链式线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(LinkList *rear)
{ 
	LinkList p,q,head;
    head = (*rear)->next;
	p = head->next;           /*  p指向第一个结点 */
	while(p!=head)                /*  没到表尾 */
	{
		q=p->next;
		free(p);
		p=q;
	}
	p->next=head;        /* 头结点指针域指向头指针 */
    *rear = p;  /*完成指向*/
	return OK;
}

Status DestroyList(LinkList *L) { 
    /* 操作结果:销毁线性表L */ 
    LinkList q,p=(*L)->next; 
    /* p指向头结点 */ 
    while(p!=(*L)) { 
        /* 没到表尾 */ 
        q=p->next; 
        free(p); 
        p=q; 
    } 
    free(*L); 
    *L=NULL; 
    return OK;
}

/* 初始条件:链式线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(LinkList rear)
{
    int i=0;
    LinkList head,p;
    head = rear->next; /* p指向第一个结点 */
    p = head->next;
    while(p!=head)                        
    {
        i++;
        p=p->next;
    }
    return i;
}

/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(LinkList rear,int i,ElemType *e)
{
	int j;
	LinkList p,head;		/* 声明一结点p */
	p = rear->next->next;		/* 让p指向链表L的第一个结点 */
    head = rear->next;   
    if (p == head) return ERROR; 
    if (i<1 || i>ListLength(rear)) return ERROR;
	j = 1;		/*  j为计数器 */    
	while (j<i) 
	{   
		p = p->next;  /* 让p指向下一个结点 */
		++j;
	}
    
	*e = p->data;   /*  取第i个元素的数据 */

	return OK;
}

/* 初始条件:链式线性表L已存在 */
/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int LocateElem(LinkList rear,ElemType e)
{
    int i=0;
    LinkList p=rear->next->next,head = rear->next;
    while(p->next!=head)
    {
        i++;
        if(p->data==e) /* 找到这样的数据元素 */
            return i;
        p=p->next;
    }
    return 0;
}


/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *rear,int i,ElemType e)
{ 
	int j;
	LinkList p,s;
    p = (*rear)->next;  	
    if(i<1||i>ListLength(*rear)+1) 
        /* 无法在第i个元素之前插入 */ 
        return ERROR;
    j = 1;
	while (j < i)     /* 寻找第i个结点 */
	{
		p = p->next;
		++j;
	}
	s = (LinkList)malloc(sizeof(Node));  /*  生成新结点 */
    if(!s) return ERROR;
	
    s->next = p->next;      /* 将p的后继结点赋值给s的后继  */
	p->next = s;          /* 将s赋值给p的后继 */
    s->data = e; 
    
    if(p->next ==(*rear)->next) 
    {
        /* 改变尾结点 */ 
        *rear=s; 
    }
	return OK;
}

/* 初始条件:链式线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(LinkList *rear,int i,ElemType *e) 
{ 
	int j;
	LinkList p,q;
	p = (*rear)->next;
	j = 1;
    if (i<1 || i>ListLength(*rear)) return ERROR;
	while (j < i)	/* 遍历寻找第i个元素 */
	{
        p = p->next;
        ++j;
	}
	q = p->next;
    p->next = q->next;
	*e = q->data;               /* 将q结点中的数据给e */
    if (q == *rear)/*释放之前如果q是尾节点*/
        *rear = p;               /*调整尾节点为p*/
	free(q);                    /* 让系统回收此结点,释放内存 */
    q = NULL;   
	return OK;
}

/* 初始条件:链式线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(LinkList L)
{
    LinkList p,head;
    head = L->next;
    p = head->next;
    while(p!=head)/*头指针不遍历*/
    {
        visit(p->data);
        p=p->next;
    }
    printf("\n");
    return OK;
}

/*  随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
void CreateListHead(LinkList *L, ElemType n) 
{
	LinkList p,head;
    head = (*L)->next;
    p = (LinkList)malloc(sizeof(Node)); /*  生成新结点 */
    p->data = n;            
    p->next = head->next;    
    head->next = p;
    if (p->next == head)	
        *L = p;					
}


void CreateListTail(LinkList *rear, ElemType n) 
{
	LinkList p,head;
    head = (*rear)->next;
    p = (Node *)malloc(sizeof(Node)); /*  生成新结点 */
    if (!p) return ERROR;
    p->data = n;   
    p->next=(*rear)->next; 
    (*rear)->next = p; 
    *rear = p; 
}
void unionL(LinkList *La,LinkList *Lb)
{
    LinkList head = (*La)->next, p = (*Lb)->next;    
    (*La)->next = (*Lb)->next->next;
    (*Lb)->next = head;
    *La = *Lb;
    free(p);
    p = NULL;
}
int main()
{        
    LinkList rearA,rearB;
    ElemType e;
    Status i;
    int j,k;
    InitList(&rearA);

    
    for(j=1;j<=5;j++)
    {
        CreateListTail(&rearA,j);
    }
    printf("在rearA的表尾巴插入后:rearA.data=");
    ListTraverse(rearA); 

    i = ListEmpty(rearA);
    printf("表当前状态(空表:1/非空表:0):> %d\n",i);

    ClearList(&rearA);
    printf("rearA->data:%d,rearA:%d,rearA->next:%d\n",rearA->data,rearA,rearA->next);
    i = ListEmpty(rearA);
    printf("表当前状态(空表:1/非空表:0):> %d\n",i);
    
    ListInsert(&rearA,1,1000);
    CreateListHead(&rearA, 100);
    
    printf("rearA清空再赋值后:rearA.data=");
    ListTraverse(rearA);

    printf("rearA->data:%d\n",rearA->data);


    InitList(&rearB);
    for(j=15;j<=20;j++)
    {
        CreateListTail(&rearB,j);
    }
    printf("在rearB的表尾巴插入后:rearB.data=");
    ListTraverse(rearB); 

    unionL(&rearA,&rearB);
    
    printf("unionL:rear.data=");
    ListTraverse(rearA);
     
    k = LocateElem(rearA, 1000);
    printf("1000是第%d个元素\n",k);

    k = ListLength(rearA);
    printf("当前表长为%d\n",k);    

    i = GetElem(rearA,k,&e);
    printf("第%d个元素存在状态:%d,值是%d\n",k,i,e);

    ListDelete(&rearA,k,&e);
    printf("删除第%d个元素,值是%d\n",k,e);

    k = ListLength(rearA);
    printf("当前表长为%d\n",k);
    

    printf("rearA当前状态:rearA.data=");
    
    ListTraverse(rearA);

    printf("rearA->data:%d,rearA->next->data:%d\n",rearA->data,rearA->next->data);

    ClearList(&rearA);

    i = ListEmpty(rearA);
    printf("清空表后状态判定(空表:1/非空表:0):> %d\n",i);

    DestroyList(&rearA);

    return 0;
}

输出结果: 

在rearA的表尾巴插入后:rearA.data=1 2 3 4 5 
表当前状态(空表:1/非空表:0):> 0
rearA->data:11558192,rearA:11539424,rearA->next:11539424
表当前状态(空表:1/非空表:0):> 1
rearA清空再赋值后:rearA.data=100 1000 
rearA->data:1000
在rearB的表尾巴插入后:rearB.data=15 16 17 18 19 20
unionL:rear.data=100 1000 15 16 17 18 19 20
1000是第2个元素
当前表长为8
第8个元素存在状态:1,值是20
删除第8个元素,值是20
当前表长为7
rearA当前状态:rearA.data=100 1000 15 16 17 18 19
rearA->data:19,rearA->next->data:11558192
清空表后状态判定(空表:1/非空表:0):> 1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值