循环单链表实现

/********************************************************

* SClist.h头文件

/********************************************************/

#ifndef __SCLIST_H__

#define __SCLIST_H__

#include<stdio.h>

#include<malloc.h>

#include<assert.h>

typedef int ElemType;

typedef struct Node { //定义结构体

ElemType data;

struct Node *next;

}Node,*PNode;

typedef struct List { //定义头尾节点及链表长度

PNode first;

PNode last;

size_t size;

}List;

void InitSClist(List *list);//初始化循环单链表

void push_back(List *list, ElemType x);//在循环单链表的末尾插入元素

void push_front(List *list, ElemType x);//在循环单链表的头部插入元素

void show_list(List *list);//打印循环单链表

void pop_back(List *list);//删除循环单链表的最后一个元素

void pop_front(List *list);//删除循环单链表的第一个元素

void insert_val(List *list, ElemType val);//将数据元素插入到循环单链表中(要求此时循环单链表中的数据元素顺序排列)

Node* find(List *list, ElemType x);//查找循环单链表中数据值为x的结点

int length(List *list);//求循环单链表的长度

void delete_val(List *list, ElemType x);//按值删除循环单链表中的某个数据元素

void sort(List *list);//对循环单链表进行排序

void reverse(List *list);//逆置循环单链表

void clear(List *list);//清除循环单链表

void destroy(List *list);//摧毁循环单链表

//优化

Node* _buynode(ElemType x);//创建结点

#endif

/********************************************************

* SClist.c文件

/********************************************************/

#include"SClist.h"

/* 创建新节点 */

Node* _buynode(ElemType x) {

Node *s = (Node*)malloc(sizeof(Node));

assert(s != NULL);

s->data = x;

s->next = NULL;

return s;

}

/* 初始化链表 */

void InitSClist(List *list) {

Node *s = (Node*)malloc(sizeof(Node));

assert(s != NULL);

list->first = list->last = s;

list->last->next = list->first;//让链表最后一个结点的指针域指向头结点,从而时链表循环

list->size = 0;

}

/* 尾部插入元素 */

void push_back(List *list, ElemType x) {

Node *s = _buynode(x);

list->last->next = s; //尾插

list->last = s; //赋地址

list->last->next = list->first;

list->size++;

}

/* 头部插入元素 */

void push_front(List *list, ElemType x) {

Node *s = _buynode(x);

s->next = list->first->next; //头插

list->first->next = s;

if (list->last == list->first)

list->last = s;

list->size++;

}

/* 打印链表 */

void show_list(List *list) {

Node *p = list->first->next;

while (p != list->first) {

printf("%d->", p->data);

p = p->next;

}

printf("Nul.\n");

}

/* 尾部释放一个元素 */

void pop_back(List *list) {

if (list->size == 0)

return;

Node *p = list->first;

while (p->next != list->last)

p = p->next; //找到尾部节点的上一个节点

free(list->last); //释放尾部元素

list->last = p; //p节点赋给尾部节点

list->last->next = list->first; //再使链表指向头节点

list->size--;

}

/* 从头释放一个元素 */

void pop_front(List *list) {

if (list->size == 0)

return;

Node *p = list->first->next;

list->first->next = p->next;

if (list->size == 1) //判断表中是否只有一个元素

list->last = list->first;

free(p);

list->size--;

}

/* 由小到大插入元素 */

void insert_val(List *list, ElemType x) {

Node *p = list->first;

while (p->next != list->last && p->next->data < x) //轮询找出大于X的元素并在前面插入

p = p->next;

if (p->next == list->last && p->next->data < x) //只有一个元素

push_back(list, x);

else { //没有元素

Node *s = _buynode(x);

s->next = p->next;

p->next = s;

list->size++;

}

}

/* 查找链表元素 */

Node* find(List *list, ElemType key) {

if (list->size == 0) //链表不存在

return NULL;

if (p == list->first) //链表为空

return NULL;

Node *p = list->first->next;

while(p != list->first && p->data != key)

p = p->next;

return p;

}

/* 链表长度 */

int length(List *list) {

return list->size;

}

/* 删除链表元素 */

void delete_val(List *list, ElemType x) {

if (p == NULL) {

return;

}

if (list->size == 0)

return;

Node *p = find(list, x); //找出元素

if (p == list->last) //p为尾节点

pop_back(list);

else { //p不为尾节点,删除p

Node *q = p->next;

p->next = q->next;

free(q);

list->size--;

}

}

/* 对循环单链表进行排序 */--------------?

void sort(List *list) {

if (list->size == 0 || list->size == 1) //链表长度为0或1不排序

return;

Node *s = list->first->next; //第一个元素节点

Node *q = s->next; //第二个元素节点

list->last->next = NULL; //断开链表连接

list->last = s;

list->last->next = list->first;

while (q != NULL) {

s = q;

q = q->next;

Node *p = list->first;

while (p->next != list->last && p->next->data < s->data)

p = p->next;

if (p->next == list->last &&p->next->data < s->data) {

list->last->next = s;

list->last = s;

list->last->next = list->first;

}

else {

s->next = p->next;

p->next = s;

}

}

}

/* 链表逆序 */ ---------------->

void reverse(List *list) {

if (list->size == 0 || list->size == 1) //没有元素或单个元素则忽略

return;

Node *p = list->first->next;

Node *q = p->next;

list->last->next = NULL;

list->last = p;

list->last->next = list->first;

while (q != NULL) {

p = q;

q = q->next;

p->next = list->first->next;

list->first->next = p;

}

}

/* 释放链表所有元素 */

void clear(List *list) {

Node *p = list->first->next;

while (p != list->first) {

list->first->next = p->next;

free(p);

p = list->first->next;

}

list->last = list->first;

list->last->next = list->first;

list->size = 0;

}

/* 摧毁链表 */

void destroy(List *list) {

clear(list);

free(list->first);

list->first = list->last = NULL;

}

/********************************************************

* main函数

/********************************************************/

#include"SClist.h"

void main() {

List mylist;

InitSClist(&mylist);

ElemType item;

Node *p = NULL;

int select = 1;

while (select) {

printf("*******************************************\n");

printf("*[1]  push_back        [2]  push_front    *\n");

printf("*[3]  show_list           [4]  pop_back      *\n");

printf("*[5]  pop_front          [6]  insert_val    *\n");

printf("*[7]  find                    [8]  length        *\n");

printf("*[9]  delete_val         [10] sort          *\n");

printf("*[11] reverse             [12] clear         *\n");

printf("*[13*] destroy             [0]  quit_system   *\n");

printf("*******************************************\n");

printf("请选择:>>");

scanf("%d", &select);

if (select == 0) break;

switch (select) {

case 1:

printf("请输入要插入的数据(-1结束):>");

while ( scanf("%d", &item) && ( item != -1) ){

push_back(&mylist, item);

}

break;

case 2:

printf("请输入要插入的数据(-1结束):>");

while ( scanf("%d", &item) && ( item != -1) ){

push_front(&mylist, item);

}

break;

case 3:

show_list(&mylist);

break;

case 4:

pop_back(&mylist);

break;

case 5:

pop_front(&mylist);

break;

case 6:

printf("请输入要插入的数据:>");

scanf("%d", &item);

insert_val(&mylist, item);

break;

case 7:

printf("请输入要查找的数据:>");

scanf("%d", &item);

p = find(&mylist, item);

if (p == NULL)

printf("要查找的数据在单链表中不存在!\n");

break;

case 8:

printf("单链表的长度为%d\n", length(&mylist));

break;

case 9:

printf("请输入要删除的值:>");

scanf("%d", &item);

delete_val(&mylist, item);

break;

case 10:

sort(&mylist);

break;

case 11:

reverse(&mylist);

break;

case 12:

clear(&mylist);

break;

//case 13: //推出再释放

//destroy(&mylist);

//break;

default:

printf("选择错误,请重新选择!\n");

break;

}

}

destroy(&mylist);

}

原文地址:https://www.cnblogs.com/ownDefine/p/10802087.html

时间: 2024-10-27 01:59:32

循环单链表实现的相关文章

02循环单链表

循环单链表定义:将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成了 一个环,这种头尾相接的单链表成为单循环链表. 循环链表的数据结构: 1 /* c2-2.h 线性表的单链表存储结构 */ 2 struct LNode 3 { 4 ElemType data; 5 struct LNode *next; 6 }; 7 typedef struct LNode *LinkList; /* 另一种定义LinkList的方法 */ 代码实现: 1 2 3 /* bo2-4.c 设立

循环单链表

//函数声明部分:#include"CirLinkList.h" #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> #include<stdlib.h> typedef int ElemType; typedef struct linknode { ElemType data; struct linknode *next; }node; void judgement_NULL(node * p); node 

c语言循环单链表

/************************************************************************* > File Name: singleLineTable.c > Author: zshh0604 > Mail: [email protected] > Created Time: 2014年10月15日 星期三 11时34分08秒 **************************************************

_DataStructure_C_Impl:循环单链表

//CycList:循环单链表 #include<stdio.h> #include<stdlib.h> typedef int DataType; typedef struct Node{ DataType data; struct Node *next; }ListNode,*LinkList; //创建一个不带头结点的循环单链表 LinkList CreateCycList(int n){ DataType e; LinkList head=NULL; ListNode *p

用循环单链表实现约瑟夫环

题目:n个人编号分别是1,2,3,...,n,围坐在一张圆桌周围,从编号为k的人开始报数,数到m的人出列.然后他的下一个人开始报数,数到m的那个人又出列:依次循环,直到所有人出列. struct LNode{ int data; LNode *next; }; //n为总人数,k为第一个开始报数的人,m为出列者喊到的数 void solve(int k,int m, int n) { if(k>n || n<=0 || m<=0) { throw "Invalid argume

【C语言数据结构】循环单链表

CircleLinkList.h #ifndef CIRCLE_LINK_LIST #define CIRCLE_LINK_LIST //链表节点 typedef struct _CircleLinkListNode {     struct _CircleLinkListNode *next; }CircleLinkListNode; //循环单链表 typedef void CircleLinkList; /*  * 创建循环单链表  * @return 返回循环单链表的指针  */ Cir

【线性表5】线性表的链式实现:循环单链表

简介 循环单链表 是在在单链表的基础上,用最后的一个结点的指针域指向头结点形成的.因此它在逻辑上是一个环形结构. 循环单链表在实际编程中很少用. 要点:1.遍历结束的标志是 p == [头结点地址],而不是p==NULL 2.表为空的判断标志是:   if( head->next == head   ) 3.在单循环链表中,从任一结点出发都可访问到表中所有结点 循环链表一般还使用尾指针rear保存最后一个结点的地址,因为使用尾指针既可以快速找到 最后一个结点,也可以快速找到头结点. 简单的代码实

【c++版数据结构】之循环单链表的实现(带头结点以及尾节点)

所实现的循环单链表的结构如下图所示: 循环单链表的实现,和上一篇文章单链表的实现大致相同点击打开链接,略有区别: 1:循环判断的条件不再是s == NULL或者s->next == NULL,而是他们是否等于头指针.2: 断开链表时的处理,尾节点的next不是NULL,而是指向头结点 具体细节参考上一篇文章 头文件:SCList.h #ifndef SCLIST_H #define SCLIST_H #include<iostream> #include<cassert> u

循环单链表,解决约瑟夫问题

约瑟夫问题: 编号为1~N的N个人按顺时针方向围坐一圈,每人持有一个密码(正整数),开始任选一个正整数作为报数上限值M,从第1个人按顺时针方向自1开始顺序报数,报到M时停止报数.报M的人出列,将他的密码作为新的M值,从他顺时针方向上的下一个人开始从1报数,如此下去,直至所有人全部出列为止. 解析: 显然当有人退出圆圈后,报数的工作要从下一个人开始继续,而剩下的人仍然围成一个圆圈,因此可以使用循环单链表.退出圆圈的工作对应着表中节点的删除操作,对于这种删除操作频繁的情况,选用效率较高的链表结构,为

数据结构之自建算法库——循环单链表

本文针对数据结构基础系列网络课程(2):线性表中第13课时双链表. 按照"0207将算法变程序"[视频]部分建议的方法,建设自己的专业基础设施算法库. 双链表算法库算法库采用程序的多文件组织形式,包括两个文件: 1.头文件:clinklist.h,包含定义双链表数据结构的代码.宏定义.要实现算法的函数的声明: #ifndef CLINKLIST_H_INCLUDED #define CLINKLIST_H_INCLUDED //循环单链表基本运算函数 typedef int ElemT