数据结构C语言版 循环链表表示和实现
数据结构(c语言版)课后习题答案完整版
![数据结构(c语言版)课后习题答案完整版](https://img.taocdn.com/s3/m/6409b408ef06eff9aef8941ea76e58fafbb0455f.png)
数据结构(c语言版)课后习题答案完整版数据结构(C语言版)课后习题答案完整版一、数据结构概述数据结构是计算机科学中一个重要的概念,用来组织和存储数据,使之可以高效地访问和操作。
在C语言中,我们可以使用不同的数据结构来解决各种问题。
本文将提供完整版本的C语言数据结构的课后习题答案。
二、顺序表1. 顺序表的定义和基本操作顺序表是一种线性表,其中的元素在物理内存中连续地存储。
在C 语言中,我们可以通过定义结构体和使用指针来实现顺序表。
以下是顺序表的一些基本操作的答案:(1)初始化顺序表```ctypedef struct{int data[MAX_SIZE];int length;} SeqList;void InitList(SeqList *L){L->length = 0;}```(2)插入元素到顺序表中```cbool Insert(SeqList *L, int pos, int elem){if(L->length == MAX_SIZE){return false; // 顺序表已满}if(pos < 1 || pos > L->length + 1){return false; // 位置不合法}for(int i = L->length; i >= pos; i--){L->data[i] = L->data[i-1]; // 向后移动元素 }L->data[pos-1] = elem;L->length++;return true;}```(3)删除顺序表中的元素```cbool Delete(SeqList *L, int pos){if(pos < 1 || pos > L->length){return false; // 位置不合法}for(int i = pos; i < L->length; i++){L->data[i-1] = L->data[i]; // 向前移动元素 }L->length--;return true;}```(4)查找顺序表中的元素```cint Search(SeqList L, int elem){for(int i = 0; i < L.length; i++){if(L.data[i] == elem){return i + 1; // 找到元素,返回位置 }}return -1; // 未找到元素}```2. 顺序表习题解答(1)逆置顺序表```cvoid Reverse(SeqList *L){for(int i = 0; i < L->length / 2; i++){int temp = L->data[i];L->data[i] = L->data[L->length - 1 - i]; L->data[L->length - 1 - i] = temp;}}```(2)顺序表元素去重```cvoid RemoveDuplicates(SeqList *L){for(int i = 0; i < L->length; i++){for(int j = i + 1; j < L->length; j++){if(L->data[i] == L->data[j]){Delete(L, j + 1);j--;}}}}```三、链表1. 单链表单链表是一种常见的链式存储结构,每个节点包含数据和指向下一个节点的指针。
c语言中循环结构
![c语言中循环结构](https://img.taocdn.com/s3/m/3a13c4c9690203d8ce2f0066f5335a8103d26665.png)
c语言中循环结构循环结构在C语言中是一种非常重要的控制结构,它能够让程序重复执行某段代码,实现代码的复用和效率的提高。
循环结构主要有三种形式:while循环、do-while循环和for循环。
1. while循环while循环是一种先判断条件再执行的循环结构。
它的语法形式如下:```while (条件) {循环体语句;}```在循环开始之前,先判断条件是否成立,如果条件成立,则执行循环体语句;否则,跳过循环体语句,继续执行后面的代码。
循环体执行完毕后,再次判断条件是否成立,如果成立,则继续执行循环体语句,直到条件不成立为止。
2. do-while循环do-while循环和while循环类似,不同之处在于它是先执行循环体,再判断条件是否成立。
它的语法形式如下:```do {循环体语句;} while (条件);```在循环开始时,先执行循环体语句,然后判断条件是否成立,如果条件成立,则继续执行循环体语句,否则跳出循环。
3. for循环for循环是一种常用的循环结构,它的语法形式如下:```for (初始化表达式; 条件表达式; 更新表达式) {循环体语句;}```for循环的执行顺序是先执行初始化表达式,然后判断条件是否成立,如果条件成立,则执行循环体语句;执行完循环体语句后,再执行更新表达式,再次判断条件是否成立,以此类推。
当条件不成立时,跳出循环。
循环结构的应用非常广泛,可以用于处理各种重复性任务,比如计算数列的和、输出九九乘法表等。
下面以计算数列的和为例,演示这三种循环结构的使用。
我们来看一下使用while循环计算数列的和的代码:```#include <stdio.h>int main() {int n = 10; // 数列的长度int sum = 0; // 数列的和int i = 1; // 循环变量while (i <= n) {sum += i;i++;}printf("数列的和为:%d\n", sum);return 0;}```在这段代码中,我们使用while循环从1开始累加到n,得到数列的和。
数据结构(C语言版)(第2版)课后习题答案
![数据结构(C语言版)(第2版)课后习题答案](https://img.taocdn.com/s3/m/3458835c52ea551810a6879c.png)
数据结构(C语言版)(第2版)课后习题答案数据结构课后习题答案李冬梅目录第第第第第第第第1章绪论 ................................................ ................................................... ............... 1 2章线性表 ................................................ ................................................... ........... 5 3章栈和队列................................................. ................................................... ..... 14 4章串、数组和广义表 ................................................ ......................................... 27 5章树和二叉树 ................................................ ................................................... .. 34 6章图 ................................................ ................................................... ................... 44 7章查找 ................................................ ................................................... ............. 55 8章排序 ................................................ ................................................... . (66)II第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
c语言中的循环
![c语言中的循环](https://img.taocdn.com/s3/m/ae82fb07bc64783e0912a21614791711cc79791e.png)
c语言中的循环
C语言中的循环是一种重要的控制结构,它可以让程序重复执行某个代码块,从而实现重复性的任务。
循环分为三种类型:while、do-while 和 for 循环。
本文将分别介绍这三种循环类型的基本语法、特点和使用方法。
一、while 循环
while 循环是C语言中最简单的一种循环类型,它的基本语法如下:
```c
while (判断条件)
{
循环体语句;
}
```
while 循环的执行过程是,先对判断条件进行判断,如果条件为真,则执行循环体语句;然后再对判断条件进行判断,如果条件仍为真,则继续执行循环体语句,否则跳出循环。
示例代码:
该程序的输出结果为:1 2 3 4 5 6 7 8 9 10。
do-while 循环的特点是,无论如何都会先执行一次循环体语句,即使没有满足循环条件。
因此,它适合于那些一定要执行一次循环体语句的情况。
三、for 循环
for 循环的特点是,循环变量初始化、循环条件判断和循环变量变化都在一个语句中完成,比较简洁;循环变量的作用域只在循环内部,避免了变量重名的问题;for 循环的执行次数可以提前确定,更容易控制循环次数。
总结
循环是C语言中最基本和最常用的控制结构之一,while、do-while 和 for 循环是常见的三种循环类型。
它们的基本语法和特点不同,应根据具体情况选择合适的循环类型。
在使用循环时,应注意循环条件的正确性,避免死循环或漏加循环体语句的情况。
数据结构-chap2 (3)循环链表
![数据结构-chap2 (3)循环链表](https://img.taocdn.com/s3/m/7cdae271a26925c52cc5bf74.png)
head->next=NULL; while(p!=NULL) {r=p->next; head->next=p; p=r; } return(head); }∥invert
∥p为工作指针,指向第一个元素
∥臵空链表 ∥将原链表的元素按头插法插入 ∥暂存p的后继 ∥头结点的指针域指向新插入的结点 ∥恢复待处理结点
A.插入、删除不需要移动元素
B.可随机访问任一元素 C.不必事先估计存储空间 D.所需空间与线性长度成正比
试述头指针、头结点、元素结点、首元结点的区别。 单链表中,增加一个头结点的目的是为了( )。 【江苏大学 2005 一.3(2分)】 A.使单链表至少有一个结点 B.标识表结点中首结点的位臵
C.方便运算的实现
【解答】单循环链表中无论设置尾指针还是头指针都可以
遍历到表中任一个结点。设置尾指针时,若在表尾进行插 入元素或删除第一元素,操作可在O(1)时间内完成;若只 设置头指针,在表尾进行插入或删除操作,需要遍历整个 链表,时间复杂度为O(n)。
在循环链表中寻找结点的直接后继很简单,只需要O(1); 但要寻找结点的直接前趋需要循环一遍,需要O(n)。
C. (p->rlink)->llink=p
D. p->rlink=(p->llink)->llink
p->rlink=(p->rlink)->rlink
p->llink=(p->rlink)->rlink;
【西安电子科技大学 1998 一、1(2分)】
试述头指针、头结点、元素结点、首元结点的区别。 •在单链表、双链表、单循环链表中,若知道指针p指向某结点, 能否删除该结点,时间复杂度如何? 【解答】以上三种链表中,若知道指针p指向某结点,都能 删除该结点。
C语言的循环链表和约瑟夫环
![C语言的循环链表和约瑟夫环](https://img.taocdn.com/s3/m/25d3a79abdeb19e8b8f67c1cfad6195f312be873.png)
C语言的循环链表和约瑟夫环C语言的循环链表和约瑟夫环约瑟夫问题)是一个数学的应用问题,对于学习C语言四非常挺有帮助的,下面是店铺为大家搜集整理出来的有关于C语言的循环链表和约瑟夫环,一起了解下吧!循环链表的实现单链表只有向后结点,当单链表的尾链表不指向NULL,而是指向头结点时候,形成了一个环,成为单循环链表,简称循环链表。
当它是空表,向后结点就只想了自己,这也是它与单链表的主要差异,判断node->next是否等于head。
代码实现分为四部分:1. 初始化2. 插入3. 删除4. 定位寻找代码实现:1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1void ListInit(Node *pNode){int item;Node *temp,*target;cout<<"输入0完成初始化"<<endl; cin="">>item;if(!item)return ;if(!(pNode)){ //当空表的时候,head==NULLpNode = new Node ;if(!(pNode))exit(0);//未成功申请pNode->data = item;pNode->next = pNode;}else{//for(target = pNode;target->next!=pNode;target = target->next);4 15 16 17 18 19 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3temp = new Node;if(!(temp))exit(0);temp->data = item;temp->next = pNode;target->next = temp;}}}void ListInsert(Node *pNode,int i){ //参数是首节点和插入位置Node *temp;Node *target;int item;cout<<"输入您要插入的值:"<<endl; cin="">>item;if(i==1){temp = new Node;if(!temp)exit(0);temp->data = item;for(target=pNode;target->next != pNode;target = target->next);temp->next = pNode;target->next = temp;pNode = temp;}else{target = pNode;for (int j=1;j<i-1;++j) target="target-">next;temp = new Node;if(!temp)exit(0);temp->data = item;temp->next = target->next;target->next = temp;}}void ListDelete(Node *pNode,int i){Node *target,*temp;if(i==1){for(target=pNode;target->next!=pNode;target=target ->next);temp = pNode;//保存一下要删除的首节点 ,一会便于释放6 37 38 39 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5pNode = pNode->next;target->next = pNode;temp;}else{target = pNode;for(int j=1;j<i-1;++j) target="target-">next;temp = target->next;//要释放的nodetarget->next = target->next->next;temp;}}int ListSearch(Node *pNode,int elem){ //查询并返回结点所在的位置Node *target;int i=1;for(target = pNode;target->data!=elem && target->next!= pNode;++i)target = target->next;if(target->next == pNode && target->data!=elem)return 0;else return i;}</i-1;++j)></i-1;++j)></endl;></endl;>5 96 0 6 1 6 2 6 3 6 4 6 5 6 6 67 68 69 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 8约瑟夫问题约瑟夫环(约瑟夫问题)是一个数学的'应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。
《C语言链表》课件
![《C语言链表》课件](https://img.taocdn.com/s3/m/c85a2256f08583d049649b6648d7c1c708a10be4.png)
详细描述
删除链表中的节点需要找到要删除的节点,修改其前一个节点的指针,使其指向要删除节点的下一个 节点,然后将要删除节点的指针置为NULL。如果要删除的是头节点或尾节点,还需要对头指针或尾 指针进行相应的修改。
遍历链表
总结词
了解如何遍历链表中的所有节点
VS
详细描述
遍历链表需要从头节点开始,依次访问每 个节点,直到达到链表的尾部。在遍历过 程中,可以使用一个指针变量来指向当前 节点,每次循环将指针向后移动一个节点 ,即修改指针的next指针。
链表和循环链表的主要区别在于它们的最后一个节点指向的方向。在链表中,最后一个节点指向NULL; 而在循环链表中,最后一个节点指向第一个节点。循环链表具有更好的性能,但实现起来相对复杂一些 。
05
总结与展望
总结链表的重要性和应用场景
总结1
链表作为C语言中一种基本的数据结构,在计算机科学中 有着广泛的应用。通过学习链表,可以更好地理解数据 结构的基本概念,提高编程能力和解决实际问题的能力 。
详细描述
合并两个有序链表可以通过比较两个链表的 节点值来实现。从头节点开始比较,将较小 的节点添加到结果链表中,并将指针向后移 动。重复此过程直到其中一个链表为空。如 果还有剩余的节点,将其添加到结果链表的 末尾。这种方法的时间复杂度为O(n),其中
n为两个链表中节点的总数。
04
常见错误与注意事项
内存泄漏问题
内存泄漏定义
在C语言中,内存泄漏是指在使用动 态内存分配函数(如malloc、calloc 、realloc等)分配内存后,未能正确 释放这些内存,导致程序运行过程中 不断占用越来越多的内存,最终可能 导致程序崩溃或性能下降。
c语言数据结构及算法
![c语言数据结构及算法](https://img.taocdn.com/s3/m/7c9e465ac4da50e2524de518964bcf84b8d52d5d.png)
C语言是一种广泛应用于编程和软件开发的编程语言,它提供了一系列的数据结构和算法库,使得开发者能够在C语言中使用这些数据结构和算法来解决各种问题。
以下是C语言中常用的数据结构和算法:数据结构:1. 数组(Array):一组相同类型的元素按顺序排列而成的数据结构。
2. 链表(Linked List):元素通过指针连接而成的数据结构,可分为单向链表、双向链表和循环链表等。
3. 栈(Stack):具有后进先出(LIFO)特性的数据结构,可用于实现函数调用、表达式求值等。
4. 队列(Queue):具有先进先出(FIFO)特性的数据结构,可用于实现任务调度、缓冲区管理等。
5. 树(Tree):一种非线性的数据结构,包括二叉树、二叉搜索树、堆、A VL树等。
6. 图(Graph):由节点和边组成的数据结构,可用于表示网络、关系图等。
7. 哈希表(Hash Table):基于哈希函数实现的数据结构,可用于高效地查找、插入和删除元素。
算法:1. 排序算法:如冒泡排序、插入排序、选择排序、快速排序、归并排序等。
2. 查找算法:如线性查找、二分查找、哈希查找等。
3. 图算法:如深度优先搜索(DFS)、广度优先搜索(BFS)、最短路径算法(Dijkstra、Floyd-Warshall)、最小生成树算法(Prim、Kruskal)等。
4. 字符串匹配算法:如暴力匹配、KMP算法、Boyer-Moore 算法等。
5. 动态规划算法:如背包问题、最长公共子序列、最短编辑距离等。
6. 贪心算法:如最小生成树问题、背包问题等。
7. 回溯算法:如八皇后问题、0-1背包问题等。
这只是C语言中常用的一部分数据结构和算法,实际上还有更多的数据结构和算法可以在C语言中实现。
开发者可以根据具体需求选择适合的数据结构和算法来解决问题。
同时,C语言也支持自定义数据结构和算法的实现,开发者可以根据需要进行扩展和优化。
链表(单链表 双向循环)实验报告讲解
![链表(单链表 双向循环)实验报告讲解](https://img.taocdn.com/s3/m/4619e343f46527d3250ce029.png)
数据结构实验报告T1223-3-21余帅实验一实验题目:仅仅做链表部分难度从上到下1.双向链表,带表头,线性表常规操作。
2.循环表,带表头,线性表常规操作。
3.单链表,带表头,线性表常规操作。
实验目的:了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。
实验要求:常规操作至少有:1.数据输入或建立2.遍历3.插入4.删除必须能多次反复运行实验主要步骤:1、分析、理解给出的示例程序。
2、调试程序,并设计输入数据,测试程序的如下功能:1.数据输入或建立2.遍历3.插入4.删除单链表示意图:headhead head 创建删除双向循环链表示意图:创建程序代码://单链表#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node *next;};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;searchp = searchp->next;count++;}searchp->next = NULL;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>=count)return range_error;node *newnodep=new node,*searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next=followp->next; //注意此处的次序相关性followp->next=newnodep;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp;if(empty())return underflow;searchp = headp->next;cout<<"连表中的数据为:"<<endl;while(searchp!=NULL){cout<<searchp->data<<" ";searchp = searchp->next;}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonfacevoid clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}/* 功能:用双向循环链表存储数据1.创建链表2.增加结点3.删除结点4.遍历链表制作人:余帅内容:239行*/#include<iostream.h>#include<windows.h>const MAX=5;enum returninfo{success,fail,overflow,underflow,range_error}; int defaultdata[MAX]={11,22,33,44,55};class node{public:int data;node * next; //指向后续节点node * pre; //指向前面的节点};class linklist{private:node *headp;protected:int count;public:linklist();~linklist();bool empty();void clearlist();returninfo create(void);returninfo insert(int position,const int &item);returninfo remove(int position) ;returninfo traverse(void);};linklist::linklist(){headp = new node;headp->next = NULL;headp->pre = NULL;count=0;}linklist::~linklist(){clearlist();delete headp;}bool linklist::empty(){if(headp->next==NULL)return true;elsereturn false;}void linklist::clearlist(){node *searchp=headp->next,*followp=headp;while(searchp->next!=NULL){followp=searchp;searchp=searchp->next;delete followp;}headp->next = NULL;headp->pre = NULL;count = 0;}returninfo linklist::create(){node *searchp=headp,*newnodep;for(int i=0;i<MAX;i++){newnodep = new node;newnodep->data = defaultdata[i];newnodep->next = NULL;searchp->next = newnodep;newnodep->pre = searchp;searchp = searchp->next;count++;}searchp->next = headp;headp->pre = searchp;traverse();return success;}returninfo linklist::insert(int position,const int &item) //插入一个结点{if(position<=0 || position>count+1)return range_error;node *newnodep=new node;node *searchp=headp->next,*followp=headp;for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}newnodep->data=item; //给数据赋值newnodep->next = searchp;searchp->pre = newnodep;followp->next = newnodep;newnodep->pre = followp;count++; //计数器加一return success;}returninfo linklist::remove(int position) //删除一个结点{if(empty())return underflow;if(position<=0||position>=count+1)return range_error;node *searchp=headp->next,*followp=headp; //这里两个指针的初始值设计一前一后for(int i=1; i<position && searchp!=NULL;i++){followp=searchp;searchp=searchp->next;}followp->next=searchp->next; //删除结点的实际语句searchp->next->pre = followp;delete searchp; //释放该结点count--; //计数器减一return success;}returninfo linklist::traverse(void){node *searchp1,*searchp2;if(empty())return underflow;searchp1 = headp;searchp2 = headp;cout<<"连表中的数据为:"<<endl;cout<<"从左至右读取:";while (searchp1->next!=headp ) {searchp1 = searchp1 ->next;cout << searchp1->data<<" ";}cout<<endl;cout<<"从右至左读取:";while (searchp2->pre!=headp ) {searchp2 = searchp2 ->pre;cout << searchp2->data<<" ";}cout<<endl;return success;}class interfacebase{public:linklist listface; //定义一个对象Cskillstudyonface void clearscreen(void);void showmenu(void);void processmenu(void);};void interfacebase::clearscreen(void){system("cls");}void interfacebase::showmenu(void){cout<<"================================"<<endl;cout<<" 功能菜单 "<<endl;cout<<" 1.创建链表 "<<endl;cout<<" 2.增加结点 "<<endl;cout<<" 3.删除结点 "<<endl;cout<<" 4.遍历链表 "<<endl;cout<<" 0.结束程序 "<<endl;cout<<"======================================"<<endl;cout<<"请输入您的选择:";}void interfacebase::processmenu(void){int returnvalue,item,position;char menuchoice;cin >>menuchoice;switch(menuchoice) //根据用户的选择进行相应的操作{case '1':returnvalue=listface.create();if(returnvalue==success)cout<<"链表创建已完成"<<endl;break;case '2':cout<<"请输入插入位置:"<<endl;cin>>position;cout<<"请输入插入数据:"<<endl;cin>>item;returnvalue = listface.insert(position,item);if(returnvalue==range_error)cout<<"数据个数超出范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '3':cout<<"输入你要删除的位置:"<<endl;cin>>position;returnvalue = listface.remove(position);if(returnvalue==underflow)cout<<"链表已空"<<endl;else if(returnvalue==range_error)cout<<"删除的数据位置超区范围"<<endl;elsecout<<"操作成功!!!"<<endl;break;case '4':listface.traverse();break;case '0':cout<<endl<<endl<<"您已经成功退出本系统,欢迎再次使用!!!"<<endl;system("pause");exit(1);default:cout<<"对不起,您输入的功能编号有错!请重新输入!!!"<<endl;break;}}void main(){interfacebase interfacenow;linklist listnow;system("color f0");interfacenow.clearscreen();while(1){interfacenow.showmenu();interfacenow.processmenu();system("pause");interfacenow.clearscreen();}}运行结果:1.创建链表:2.增加结点3.删除结点心得体会:本次实验使我们对链表的实质了解更加明确了,对链表的一些基本操作也更加熟练了。
数据结构:循环队列(C语言实现)
![数据结构:循环队列(C语言实现)](https://img.taocdn.com/s3/m/2b2b29bbcf84b9d529ea7a21.png)
数据结构:循环队列(C语言实现)生活中有很多队列的影子,比如打饭排队,买火车票排队问题等,可以说与时间相关的问题,一般都会涉及到队列问题;从生活中,可以抽象出队列的概念,队列就是一个能够实现“先进先出”的存储结构。
队列分为链式队列和静态队列;静态队列一般用数组来实现,但此时的队列必须是循环队列,否则会造成巨大的内存浪费;链式队列是用链表来实现队列的。
这里讲的是循环队列,首先我们必须明白下面几个问题一、循环队列的基础知识1.循环队列需要几个参数来确定循环队列需要2个参数,front和rear2.循环队列各个参数的含义(1)队列初始化时,front和rear值都为零;(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置;(3)当队列为空时,front与rear的值相等,但不一定为零;3.循环队列入队的伪算法(1)把值存在rear所在的位置;(2)rear=(rear+1)%maxsize ,其中maxsize代表数组的长度;程序代码:[cpp]view plaincopy1.bool Enqueue(PQUEUE Q, int val)2.{3.if(FullQueue(Q))4.return false;5.else6. {7. Q->pBase[Q->rear]=val;8. Q->rear=(Q->rear+1)%Q->maxsize;9.return true;10. }11.}4.循环队列出队的伪算法(1)先保存出队的值;(2)front=(front+1)%maxsize ,其中maxsize代表数组的长度;程序代码:[cpp]view plaincopy1.bool Dequeue(PQUEUE Q, int *val)2.{3.if(EmptyQueue(Q))4. {5.return false;6. }7.else8. {9. *val=Q->pBase[Q->front];10. Q->front=(Q->front+1)%Q->maxsize;11.return true;12. }13.}5.如何判断循环队列是否为空if(front==rear)队列空;else队列不空;[cpp]view plaincopy1.bool EmptyQueue(PQUEUE Q)2.{3.if(Q->front==Q->rear) //判断是否为空4.return true;5.else6.return false;7.}6.如何判断循环队列是否为满这个问题比较复杂,假设数组的存数空间为7,此时已经存放1,a,5,7,22,90六个元素了,如果在往数组中添加一个元素,则rear=front;此时,队列满与队列空的判断条件front=rear相同,这样的话我们就不能判断队列到底是空还是满了;解决这个问题有两个办法:一是增加一个参数,用来记录数组中当前元素的个数;第二个办法是,少用一个存储空间,也就是数组的最后一个存数空间不用,当(rear+1)%maxsiz=front时,队列满;[cpp]view plaincopy1.bool FullQueue(PQUEUE Q)2.{3.if(Q->front==(Q->rear+1)%Q->maxsize) //判断循环链表是否满,留一个预留空间不用4.return true;5.else6.return false;7.}附录:queue.h文件代码:[cpp]view plaincopy1.#ifndef __QUEUE_H_2.#define __QUEUE_H_3.typedef struct queue4.{5.int *pBase;6.int front; //指向队列第一个元素7.int rear; //指向队列最后一个元素的下一个元素8.int maxsize; //循环队列的最大存储空间9.}QUEUE,*PQUEUE;10.11.void CreateQueue(PQUEUE Q,int maxsize);12.void TraverseQueue(PQUEUE Q);13.bool FullQueue(PQUEUE Q);14.bool EmptyQueue(PQUEUE Q);15.bool Enqueue(PQUEUE Q, int val);16.bool Dequeue(PQUEUE Q, int *val);17.#endifqueue.c文件代码:[cpp]view plaincopy1.#include<stdio.h>2.#include<stdlib.h>3.#include"malloc.h"4.#include"queue.h"5./***********************************************6.Function: Create a empty stack;7.************************************************/8.void CreateQueue(PQUEUE Q,int maxsize)9.{10. Q->pBase=(int *)malloc(sizeof(int)*maxsize);11.if(NULL==Q->pBase)12. {13. printf("Memory allocation failure");14. exit(-1); //退出程序15. }16. Q->front=0; //初始化参数17. Q->rear=0;18. Q->maxsize=maxsize;19.}20./***********************************************21.Function: Print the stack element;22.************************************************/23.void TraverseQueue(PQUEUE Q)24.{25.int i=Q->front;26. printf("队中的元素是:\n");27.while(i%Q->maxsize!=Q->rear)28. {29. printf("%d ",Q->pBase[i]);30. i++;31. }32. printf("\n");33.}34.bool FullQueue(PQUEUE Q)35.{36.if(Q->front==(Q->rear+1)%Q->maxsize) //判断循环链表是否满,留一个预留空间不用37.return true;38.else39.return false;40.}41.bool EmptyQueue(PQUEUE Q)42.{43.if(Q->front==Q->rear) //判断是否为空44.return true;45.else46.return false;47.}48.bool Enqueue(PQUEUE Q, int val)49.{50.if(FullQueue(Q))51.return false;52.else53. {54. Q->pBase[Q->rear]=val;55. Q->rear=(Q->rear+1)%Q->maxsize;56.return true;57. }58.}59.60.bool Dequeue(PQUEUE Q, int *val)61.{62.if(EmptyQueue(Q))63. {64.return false;65. }66.else67. {68. *val=Q->pBase[Q->front];69. Q->front=(Q->front+1)%Q->maxsize;70.return true;71. }72.}[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]。
c语言while循环语句用法举例
![c语言while循环语句用法举例](https://img.taocdn.com/s3/m/8328fa1c814d2b160b4e767f5acfa1c7aa008215.png)
C语言while循环语句用法举例一、概述在C语言中,while循环是一种常用的循环语句,其语法简单而灵活,使用范围广泛,能够满足各种不同的循环需求。
通过不断地判断条件是否成立,while循环可以重复执行特定的代码块,直到条件不再满足为止。
二、基本语法结构在C语言中,while循环的基本语法结构如下:```while (条件) {循环体;}```其中,条件是一个逻辑表达式,如果条件成立(即返回值为真),则执行循环体中的代码;否则,跳过循环体,执行while循环后面的语句。
三、举例说明接下来,我们通过几个简单而典型的例子来展示while循环的基本用法,帮助读者更深入地理解。
1. 计算1到100的和```c#include <stdio.h>int main() {int i = 1;int sum = 0;while (i <= 100) {sum += i;i++;}printf("1到100的和为:%d\n", sum);return 0;}```在这个例子中,我们使用while循环来计算1到100的和。
通过不断递增的i值和累加的sum值,实现了对从1到100的所有数求和的功能。
2. 猜数字游戏```c#include <stdio.h>int main() {int target = 50;int guess = 0;printf("猜一个0到100之间的数字:");while (guess != target) {scanf("%d", &guess);if (guess < target) {printf("太小了,再试试:");} else if (guess > target) {printf("太大了,再试试:");} else {printf("恭喜你猜对了!\n");}}return 0;}```在这个例子中,我们利用while循环来实现一个简单的猜数字游戏。
循环单链表定义初始化及创建(C语言)
![循环单链表定义初始化及创建(C语言)](https://img.taocdn.com/s3/m/45882b27905f804d2b160b4e767f5acfa1c7830b.png)
循环单链表定义初始化及创建(C语⾔)#include <stdio.h>#include <stdlib.h>/*** 含头节点循环单链表定义,初始化及创建*/#define OK 1;#define ERROR 0;//函数返回类型,表⽰函数运⾏结果的状态typedef int Status;//定义数据元素类型typedef char ElemType;//循环单链表定义typedef struct LoopLnode {ElemType data; //数据域,这⾥是char类型变量struct LoopLnode *next; //指针域,结构体类型指针} LoopLnode, *LoopLinkList;//循环单链表初始化Status InitList(LoopLinkList *list) {(*list)=(LoopLinkList)malloc(sizeof(LoopLnode));(*list)->next=(*list);(*list)->data='T'; //测试⽤,可不写return OK;}//1."头插法"创建仅含"头指针"的单向循环链表Status CreateList_H(LoopLinkList *list,ElemType arrData[],int length){int j;for(j=length-1;j>=0;j--){//新建结点LoopLnode *node;node=(LoopLnode*)malloc(sizeof(LoopLnode));node->data=arrData[j];node->next=NULL;//插⼊循环链表node->next=(*list)->next;(*list)->next=node; //list始终指向头结点}return OK;}//2."尾插法"创建仅含"头指针"的单向循环链表Status CreateList_R(LoopLinkList *list,ElemType arrData[],int length){LoopLnode *r;r=*list;int j;for(j=0;j<length;j++) {//新建结点LoopLnode *node;node=(LoopLnode*)malloc(sizeof(LoopLnode));node->data=arrData[j];node->next=NULL;//插⼊循环链表node->next=r->next;r=node;}return OK;}//3."头插法"创建仅含"尾指针"的单向循环链表Status BuildList_H(LoopLinkList *list,ElemType arrData[],int length){int j;for(j=length-1;j>=0;j--){//新建结点LoopLnode *node;node=(LoopLnode*)malloc(sizeof(LoopLnode));node->data=arrData[j];node->next=NULL;//node插⼊1号结点,list为尾指针node->next=(*list)->next->next; //node->next=头结点->nextif((*list)->next==(*list)) (*list)=node; //当只有头结点时(插⼊第⼀个结点时,⼿动设置node为尾指针)(*list)->next->next=node; //头结点->next=node;}return OK;}//4."尾插法"创建仅含"尾指针"的单向循环链表Status BuildList_R(LoopLinkList *list,ElemType arrData[],int length) {int j;for(j=0;j<length;j++) {//新建结点LoopLnode *node;node=(LoopLnode*)malloc(sizeof(LoopLnode));node->data=arrData[j];node->next=NULL;node->next=(*list)->next; //node->next=头结点(*list) = node; //尾指针 —> node}return OK;}int main(void){//产⽣待插⼊到链表的数据ElemType data1='A',data2='B',data3='C';ElemType waitInserted[]={data1,data2,data3,};//获得数组长度int arrLength=sizeof(waitInserted)/sizeof(waitInserted[0]);/**1.头插法建⽴只含头指针循环单链表**///定义链表并初始化LoopLinkList list1;InitList(&list1);//按既定数据建⽴链表CreateList_H(&list1,waitInserted,arrLength);//测试printf("%c\n",list1->next->next->next->next->next->next->data); //B/**2.尾插法建⽴只含头指针循环单链表**///定义链表并初始化LoopLinkList list2;InitList(&list2);//按既定数据建⽴链表CreateList_R(&list2,waitInserted,arrLength);//测试printf("%c\n",list1->next->next->next->next->next->next->data); //B/**3.头插法建⽴只含尾指针循环单链表**///定义链表并初始化LoopLinkList list3;InitList(&list3);//按既定数据建⽴链表BuildList_H(&list3,waitInserted,arrLength); //list3指向表尾//测试printf("%c\n",list3->next->next->next->next->next->next->next->next->next->data); //T/**4.尾插法建⽴只含尾指针循环单链表**///定义链表并初始化LoopLinkList list4;InitList(&list4);//按既定数据建⽴链表BuildList_H(&list4,waitInserted,arrLength); //list4指向表尾//测试printf("%c\n",list4->next->next->next->next->next->next->next->next->next->next->data); //A printf("\nEND!");return0;}。
C语言-链表
![C语言-链表](https://img.taocdn.com/s3/m/fbbfd029ec630b1c59eef8c75fbfc77da2699708.png)
NWPU—CC—ZhangYanChun
13
┇
void main( )
{┇
for(i=1; i<=N; i++)
/*建立链表*/
{┇
}
for(i=1; i<=N; i++)
/*输出链表*/
{ if(i==1) p1=head;
/*p1指向首节点*/
else p1=p1->next; /*p1指向下一节点*/
第第9十页,一共2章8页。 结构体与共用体
NWPU—CC—ZhangYanChun
10
3) 重复第2步,建立并链接多个节点直至所需长
度,将末尾节点的next成员赋值0。
head
1048 p1 1370 p1
2101
2304
1012
2918
89.5
90
85
操作:
1370
1012
NULL
pp22
p2
p1=(struct student *)malloc(len);
成功,返回存储块起始指针,该指针类型为
void *;否则返回空指针(NULL)。
内存释放函数原形:void free(void *p); 功能:释放p所指向的内存块。
包含文件:malloc.h、stdlib.h中均有其原型声明。
C 程序设计
第第4十页,一共2章8页。 结构体与共用体
NWPU—CC—ZhangYanChun
第第5十页,一共2章8页。 结构体与共用体
NWPU—CC—ZhangYanChun
6
6) 链表的类型
单链表:每个节点只有一个指向后继节点的指针 双向链表:每个节点有两个用于指向其它节点的指针;
C语言中的数据结构与算法实现
![C语言中的数据结构与算法实现](https://img.taocdn.com/s3/m/a4500ec89f3143323968011ca300a6c30c22f10e.png)
C语言中的数据结构与算法实现在计算机科学中,数据结构和算法是构建程序的基础。
C语言作为一种强大而广泛使用的编程语言,提供了丰富的库函数和语法特性来支持数据结构和算法的实现。
本文将讨论C语言中常见的数据结构和算法,并通过示例代码来展示其实现方法。
一、线性数据结构1. 数组(Array)数组是C语言中最基本的数据结构之一,能够存储相同类型的数据元素。
通过索引,可以快速访问数组中的任意元素。
以下是一个简单的数组示例:```c#include <stdio.h>int main() {int arr[5] = {1, 2, 3, 4, 5};for(int i=0; i<5; i++) {printf("%d ", arr[i]);}return 0;}```2. 链表(Linked List)链表是一种动态数据结构,由节点组成,并通过指针相互连接。
链表具有灵活性,能够高效地插入和删除节点。
以下是一个简单的链表示例:```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node* next;} Node;int main() {Node* head = NULL;Node* second = NULL;Node* third = NULL;// 分配内存并赋值head = (Node*)malloc(sizeof(Node));second = (Node*)malloc(sizeof(Node));third = (Node*)malloc(sizeof(Node)); head->data = 1;head->next = second;second->data = 2;second->next = third;third->data = 3;third->next = NULL;// 遍历链表Node* ptr = head;while (ptr != NULL) {printf("%d ", ptr->data);ptr = ptr->next;}return 0;}```二、非线性数据结构1. 栈(Stack)栈是一种后进先出(LIFO)的数据结构,只允许在栈的顶部进行插入和删除操作。
数据结构实验 C语言版 线性表__C版
![数据结构实验 C语言版 线性表__C版](https://img.taocdn.com/s3/m/57a33de5856a561252d36f95.png)
2. 求表长
L.length
3. 取第i个元素
L.elem[i-1]
(0<i<L.length+1)
18
4. 元素定位操作
分析:依次取出每个元素和给定值进行比较 int LocateElem_Sq (SqList L, ElemType e, Status (*compare)(ElemType, ElemType))
6. 删除操作
线性表的删除运算是指将表的第i(1≦i≦n)个元 素删除,使长度为n的线性表: (a1,…a i-1,ai,a i+1…,an) 变成长度为n-1的线性表 (a1,…a i-1,a i+1,…,an)
操作步骤: ① 判断线性表是否为空 ② 判断i值是否合法:1≦i≦n ③ 元素前移 ④ 表长减1
2
线性结构:数据元素之间存在1对1的关系。 四个特征: ① 存在惟一的一个“第一元素” ② 存在惟一的一个“最后元素” ③ 除最后元素外,其它元素均有惟一的“后继” ④ 除第一元素外,其它元素均有惟一的“前驱”
3
2.1 线性表的类型定义
一.定义
线性表(Linear List) :由n(n≧0)个数据元素组成的 有限序列。记作: (a1,a2,…an) 其中数据元素的个数n定义为表的长度。当n=0时称 为空表 这里的数据元素ai(1≦i≦n)只是一个抽象的符号, 其具体含义在不同的情况下可以不同。 例1、26个英文字母组成的字母表 (A,B,C、…、Z) 例2、某校从1978年到1983年各种型号的计算机拥 有量的变化情况。 4 (6,17,28,50,92,188)
思考:若要直接查相等的呢?
19
5. 插入操作
线性表的插入运算是指在表的第i(1≦i≦n+1)个位置上,插 入一个新元素e,使长度为n的线性表(a1,…a i-1,ai,…,an) 变成长度为n+1的线性表 (a1,…a i-1,e,ai,…,an) 操作步骤: ① 判断i是否符合要求:1≦i≦n+1 ② 判断表长是否溢出 ③ 元素右移 ④ 插入 ⑤ 表长增1
循环链表遍历
![循环链表遍历](https://img.taocdn.com/s3/m/09f1073103020740be1e650e52ea551811a6c952.png)
循环链表遍历一、什么是循环链表循环链表是一种特殊的链表,它的最后一个节点指向头节点,形成了一个环形结构。
二、遍历循环链表的方法遍历循环链表可以利用以下两种方法:1. 利用头节点循环首先定义一个指针p指向循环链表的头节点,然后循环遍历链表,直到指针p再次指向头节点为止。
具体的遍历过程如下:p = head;do {// 遍历节点的代码p = p->next;} while (p != head);2. 利用尾节点循环定义一个指针p指向循环链表的尾节点,然后从尾节点开始循环遍历链表,直到指针p再次指向尾节点为止。
具体的遍历过程如下:p = tail;do {// 遍历节点的代码p = p->prev;} while (p != tail);三、两种方法的比较从时间复杂度来看,两种方法的时间复杂度都是O(n),因为需要遍历整个循环链表。
但是,从具体实现的角度来看,第二种方法的实现要比第一种方法复杂一些,因为需要额外定义一个指针指向循环链表的尾节点。
同时,如果循环链表的节点数量比较大,且需要遍历多次,那么第一种方法可能会比第二种方法更快,因为它不需要额外定义指针,从而节约了内存空间。
四、总结循环链表是一种特殊的链表,遍历循环链表可以利用头节点或尾节点来实现。
两种方法的时间复杂度均为O(n),但从具体实现的角度来看,第二种方法相对较复杂,需要额外定义指针。
具体选择哪种方法需要根据实际情况来决定。
同时,需要注意遍历循环链表时需要判断指针是否指向头节点或尾节点,避免陷入死循环。
《数据结构》(C语言版)严蔚敏著-数据结构实验指导
![《数据结构》(C语言版)严蔚敏著-数据结构实验指导](https://img.taocdn.com/s3/m/f9d3dff17d1cfad6195f312b3169a4517723e512.png)
《数据结构》(C语言版)严蔚敏著-数据结构实验指导/学年第学期姓名:______________学号:______________班级:______________指导教师:______________数学与统计学院2022预备实验C语言的函数数组指针结构体知识一、实验目的1、复习C语言中函数、数组、指针、结构体与共用体等的概念。
2、熟悉利用C语言进行程序设计的一般方法。
二、实验预习说明以下C语言中的概念1、函数:2、数组:3、指针:4、结构体5、共用体三、实验内容和要求1、调试程序:输出100以内所有的素数(用函数实现)。
#includeintiprime(intn){/某判断一个数是否为素数某/intm;for(m=2;m某m<=n;m++)if(n%m==0)return0;return1;}intmain(){/某输出100以内所有素数某/inti;printf(\for(i=2;i<100;i++)if(iprime(i)==1)printf(\return0;}运行结果:2、调试程序:对一维数组中的元素进行逆序排列。
#include#defineN10intmain(){2inta[N]={0,1,2,3,4,5,6,7,8,9},i,temp;printf(\for(i=0;itemp=a[i];a[i]=a[N-i-1];a[N-i-1]=temp;printf(\for(i=0;ireturn0;}运行结果:3、调试程序:在二维数组中,若某一位置上的元素在该行中最大,而在该列中最小,则该元素即为该二维数组的一个鞍点。
要求从键盘上输入一个二维数组,当鞍点存在时,把鞍点找出来。
#include#defineM3#defineN4intmain(){inta[M][N],i,j,k;printf(\请输入二维数组的数据:\\n\for(i=0;ifor(j=0;jfor(j=0;jfor(i=0;i/某找出第i行的最大值某/if(a[i][j]>a[i][k])k=j;for(j=0;jif(a[j][k]/某在第i行找到鞍点某/break;if(j==M)printf(\3}return0;}运行结果:4、调试程序:利用指针输出二维数组的元素。
c语言while循环总结
![c语言while循环总结](https://img.taocdn.com/s3/m/5e857a6f76232f60ddccda38376baf1ffd4fe37a.png)
c语言while循环总结标题:C语言while循环在C语言中,循环结构是常用的程序控制结构之一。
其中,while 循环是一种基本的循环结构,它允许我们重复执行一段代码,直到指定的条件不再满足为止。
本文将对C语言中的while循环进行总结和讲解。
一、while循环的语法结构while循环的语法结构如下:```cwhile (条件表达式){循环体语句;迭代语句;}```其中,条件表达式是一个可以返回布尔值(即真或假)的表达式,循环体语句是需要重复执行的代码块,而迭代语句则用于更新循环控制变量的值。
二、while循环的执行过程当while循环开始执行时,首先会对条件表达式进行判断。
如果条件表达式的值为真,则执行循环体语句;如果条件表达式的值为假,则跳过循环体,直接结束循环。
在每次循环执行完毕后,都会再次对条件表达式进行判断,以决定是否继续执行循环。
三、while循环的应用场景1. 一般的循环控制:当我们需要重复执行某段代码,直到满足特定条件时停止循环,就可以使用while循环。
比如,计算一个数的阶乘、求解最大公约数等问题都可以用while循环来实现。
2. 用户输入的验证:我们可以使用while循环来验证用户的输入是否符合要求。
当用户输入的数据不符合规定时,我们可以要求用户重新输入,直到输入正确为止。
3. 文件读取:在读取文件的时候,我们可以使用while循环来逐行读取文件内容,直到文件末尾。
四、while循环的注意事项1. 循环条件的判断:在使用while循环时,需要特别注意循环条件的判断。
如果循环条件一直为真,就会导致无限循环,程序将陷入死循环状态,影响程序的正常执行。
2. 循环控制变量的更新:循环体中的迭代语句用于更新循环控制变量的值。
如果忘记更新循环控制变量,循环可能无法结束,从而导致死循环。
3. 循环体语句的缩进:为了代码的可读性,建议在编写循环体语句时进行适当的缩进,以便更清晰地区分循环体和非循环体的代码。
C语言实现循环链表
![C语言实现循环链表](https://img.taocdn.com/s3/m/9dc9f6393069a45177232f60ddccda38376be1f8.png)
C语⾔实现循环链表本⽂实例为⼤家分享了C语⾔实现循环链表的具体代码,供⼤家参考,具体内容如下注意事项:1、循环链表设置尾指针。
由于在链表的操作过程中,尾指针会不断变化,所以在⼀些函数的形参中都设置指向头指针的指针。
以及链表的结束判断条件变成q是否等于尾指针。
2、注意传递的实参需要取地址3、循环链表的优势在于双链表合并,以及实现尾插法简单(⾸先新建结点指向头结点,然后把尾指针的next域指向该新建结点)4、在创建链表时,使⽤尾插法,⽽不是⽤头插法(因为头插法很难去更新尾指针,使得最后尾指针还需额外更新⼀次),直接⽤头插法建⽴的是头指针,⽽⾮尾指针代码:#include<stdio.h>#include<stdlib.h>typedef struct Node{int data;struct Node * next;}Node, *LinkList;LinkList Creat();void Destroy(LinkList *L);void Insert(LinkList *L, int val, int index);void Delete(LinkList *L, int index);void Traverse(LinkList L);int main(){LinkList L = Creat();Traverse(L);Insert(&L, 1, 5);printf("After inserting is :\n");Traverse(L);printf("After deleting is :\n");Delete(&L, 2);Traverse(L);Destroy(&L);Traverse(L);}LinkList Creat(){LinkList L = (LinkList)malloc(sizeof(Node));//⽤L指针指向新建结点,这⾥L还不算尾指针int n;L->data = -1;L->next = L;//头结点的指针域指向头结点, 注意!这⾥是对尾指针的初始化。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构C语言版循环链表表示和实现.txt37真诚是美酒,年份越久越醇香浓烈;真诚是焰火,在高处绽放才愈显美丽;真诚是鲜花,送之于人,手有余香。
/*数据结构C语言版循环链表表示和实现P35编译环境:Dev-C++ 4.9.9.2日期:2011年2月10日*/#include <stdio.h>#include <malloc.h>#include <stdlib.h>typedef int ElemType;// 线性表的单链表存储结构typedef struct LNode{ElemType data;struct LNode *next;}LNode, *LinkList;// 要好好区分什么是头结点((*L)->next),尾结点(*L),以及第一个结// 点(*L)->next->next,设立尾指针的单循环链表(头尾相接,即头结点// 与尾结点是一样的,它们都没数据域.// 构造一个空的循环链表Lint InitList_CL(LinkList *L){// 产生头结点,并使L指向此头结点*L = (LinkList)malloc(sizeof(struct LNode));if(!*L)exit(0);// 指针域指向头结点,这样就构成了一个循环,空表循环,*L为表尾(*L)->next = *L;return 1;}// 销毁循环链表Lint DestroyList_CL(LinkList *L){LinkList q,p = (*L)->next; // p指向头结点while(p != *L) // 没到表尾,*L为表尾{q = p->next;free(p);p = q;}free(*L);*L = NULL;return 1;}// 将L重置为空表int ClearList_CL(LinkList *L){LinkList p, q;*L=(*L)->next; // L指向头结点p=(*L)->next; // p指向第一个结点while(p!=*L) // 没到表尾{q=p->next;free(p);p=q;}(*L)->next=*L; // 头结点指针域指向自身return 1;}// 若L为空表,则返回1,否则返回0int ListEmpty_CL(LinkList L){if(L->next==L) // 空return 1;elsereturn 0;}// 返回L中数据元素个数int ListLength_CL(LinkList L){int i=0;LinkList p=L->next; // p指向头结点while(p!=L) // 没到表尾{i++;p=p->next;}return i;}// 当第i个元素存在时,其值赋给e并返回1,否则返回0int GetElem_CL(LinkList L,int i,ElemType *e){int j=1; // 初始化,j为计数器LinkList p=L->next->next; // p指向第一个结点if(i<=0||i>ListLength_CL(L)) // 第i个元素不存在return 0;while(j<i){// 顺指针向后查找,直到p指向第i个元素p=p->next;j++;}*e=p->data; // 取第i个元素return 1;}// 返回L中第1个与e满足关系compare()的数据元素的位序。
// 若这样的数据元素不存在,则返回值为0int LocateElem_CL(LinkList L,ElemType e,int(*compare)(ElemType,ElemType)) {int i=0;LinkList p=L->next->next; // p指向第一个结点while(p!=L->next){i++;if(compare(p->data,e)) // 满足关系return i;p=p->next;}return 0;}// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱.int PriorElem_CL(LinkList L,ElemType cur_e,ElemType *pre_e){LinkList q,p=L->next->next; // p指向第一个结点q=p->next;while(q!=L->next) // p没到表尾{if(q->data==cur_e){*pre_e=p->data;return 1;}p=q;q=q->next;}return 0;}// 若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继. int NextElem_CL(LinkList L,ElemType cur_e,ElemType *next_e){LinkList p=L->next->next; // p指向第一个结点while(p!=L) // p没到表尾{if(p->data==cur_e){*next_e=p->next->data;return 1;}p=p->next;}return 0;}// 在L的第i个位置之前插入元素eint ListInsert_CL(LinkList *L,int i,ElemType e){LinkList p=(*L)->next,s; // p指向头结点int j=0;if(i<=0||i>ListLength_CL(*L)+1) // 无法在第i个元素之前插入return 0;while(j<i-1) // 寻找第i-1个结点{p=p->next;j++;}s=(LinkList)malloc(sizeof(struct LNode)); // 生成新结点s->data=e; // 插入L中s->next=p->next;p->next=s;if(p==*L) // 改变尾结点*L=s;return 1;}// 删除L的第i个元素,并由e返回其值int ListDelete_CL(LinkList *L,int i,ElemType *e){LinkList p=(*L)->next,q; // p指向头结点int j=0;if(i<=0||i>ListLength_CL(*L)) // 第i个元素不存在return 0;while(j<i-1) // 寻找第i-1个结点{p=p->next;j++;}q=p->next; // q指向待删除结点p->next=q->next;*e=q->data;if(*L==q) // 删除的是表尾元素*L=p;free(q); // 释放待删除结点return 1;}// 依次对L的每个数据元素调用函数vi()int ListTraverse_CL(LinkList L,void(*vi)(ElemType)) {LinkList p=L->next->next;// p指向第一个结点while(p!=L->next){vi(p->data);p=p->next;}printf("\n");return 1;}// 两个仅设表尾指针的循环链表的合并(教科书P35图2.13)void MergeList_CL(LinkList *La,LinkList Lb){LinkList p=Lb->next;Lb->next=(*La)->next;(*La)->next=p->next;free(p);*La=Lb;}int compare(ElemType c1,ElemType c2){if(c1==c2)return 1;elsereturn 0;}void visit(ElemType c){printf("%d ",c);}int main(){LinkList L, La, Lb;ElemType e;int i, j, n;i=InitList_CL(&L); // 初始化单循环链表Lprintf("初始化单循环链表L i=%d (1:初始化成功)\n",i);i=ListEmpty_CL(L);printf("L是否空 i=%d(1:空 0:否)\n",i);ListInsert_CL(&L,1,3); // 在L中依次插入3,5ListInsert_CL(&L,2,5);i=GetElem_CL(L,1,&e);j=ListLength_CL(L);printf("L中数据元素个数=%d,第1个元素的值为%d。
\n",j,e);printf("L中的数据元素依次为:");ListTraverse_CL(L,visit);PriorElem_CL(L,5,&e); // 求元素5的前驱printf("5前面的元素的值为%d。
\n",e);NextElem_CL(L,3,&e); // 求元素3的后继printf("3后面的元素的值为%d。
\n",e);printf("L是否空 %d(1:空 0:否)\n",ListEmpty_CL(L));j=LocateElem_CL(L,5,compare);if(j)printf("L的第%d个元素为5。
\n",j);elseprintf("不存在值为5的元素\n");i=ListDelete_CL(&L,2,&e);printf("删除L的第2个元素:\n");if(i){printf("删除的元素值为%d,现在L中的数据元素依次为:",e);ListTraverse_CL(L,visit);}elseprintf("删除不成功!\n");printf("清空L:%d(1: 成功)\n",ClearList_CL(&L));printf("清空L后,L是否空:%d(1:空 0:否)\n",ListEmpty_CL(L));printf("销毁L:%d(1: 成功)\n",DestroyList_CL(&L));n = 5;//创建单循环链表InitList_CL(&La);for(i=1;i<=n;i++)ListInsert_CL(&La,i,i);printf("La="); // 输出链表La的内容ListTraverse_CL(La,visit);//创建单循环链表InitList_CL(&Lb);for(i=1;i<=n;i++)ListInsert_CL(&Lb,1,i*2);printf("Lb="); // 输出链表Lb的内容ListTraverse_CL(Lb,visit);MergeList_CL(&La,Lb);printf("La+Lb="); // 输出合并后的链表的内容ListTraverse_CL(La,visit);system("pause");return 0;}/*输出效果:初始化单循环链表L i=1 (1:初始化成功)L是否空 i=1(1:空 0:否)L中数据元素个数=2,第1个元素的值为3。