单链表的创建、计数打印、删除节点、增加节点、逆序操作与查找中间节点,是上上一篇的补充,gcc调试通过。
#include<stdio.h>
#include<stdlib.h> /*使用到其中的malloc和exit函数*/
#define times 4 /*用于循环次数的控制*/
static int N=4; /*静态全局变量,用于控制单链表长度*/
typedef struct _person
{
char name[12];
int age;
struct _person *next;
}stud;
stud *Create(int num) /*创建单链表的函数,num为单链表的长度*/
{
int i;
stud *h,*p,*q; /* h为头指针,指向单链表的第一个节点*/
h=(stud*)malloc(sizeof(stud));
if(h!=NULL)
{
p=h;
for(i=0;i<num;i++)
{
q=(stud*)malloc(sizeof(stud)); /* q为指向新建节点的指针*/
if(q!=NULL)
{
printf("依次输入第%d个人的姓名和年龄:\n",i+1);
scanf("%s%d",q->name,&q->age);
q->next=NULL; /*创建新节点完毕*/
p->next=q;
p=q;
}
}
}
printf("\n");
return(h);
}
stud *Delete(stud *person,int post) /*删除单链表指定位置节点的函数*/
{
int i;
stud *cur,*pre;
cur=person;
if(0==post) /*如果输入的值为0,则不删除任何节点*/
{
printf("\n注意:您决定不删除任何节点!!!\n\n");
return(person);
}
else if(post>N||post<0) /*如果输入的值大于单链表长度或者小于0,程序结束*/
{
printf("输入有误,程序终止。\n");
exit(1);
}
else
{
if(1==post) /*在单链表头部删除的情况*/
{
cur=cur->next;
person->next=cur->next;
free(cur);
}
else /*在其它位置删除的情况*/
{
for(i=2;i<post+1;i++) /*使pre成为要插入位置的上一位置的节点*/
{
cur=cur->next;
pre=cur;
}
cur=cur->next;
pre->next=cur->next;
free(cur);
}
return(person);
}
}
stud *Insert(stud *person,int post) /*在单链表指定位置插入新的节点的函数*/
{
int i;
stud *cur,*pre,*node;
if(post>N+1||post<1) /*如果输入的值大于单链表长度加1或者小于1,程序结束*/
{
printf("输入错误,程序终止。\n");
exit(1);
}
if(person!=NULL)
{
cur=person;
node=(stud*)malloc(sizeof(stud));
if(node!=NULL)
{
printf("请输入新人的姓名和年龄:\n");
scanf("%s%d",node->name,&node->age); /*为新的节点输入数据内容*/
if(1==post)
{
node->next=person->next;
person->next=node;
}
else
{
for(i=2;i<post+2;i++)
{
pre=cur;
cur=cur->next;
}
node->next=pre->next;
pre->next=node;
}
}
}
printf("\n");
return(person);
}
stud *Reverse(stud *person) /*对单链表进行逆序操作的函数*/
{
stud *cur,*tmp; //cur将代表逆序后单链表的第一个节点
//tmp代表原单链表中cur之后紧邻的节点,起交换作用
if(person!=NULL)
{
cur=person->next;
person->next=NULL; /*将原单链表置空*/
while(cur!=NULL) /*如果cur不为NULL*/
{
tmp=cur->next; /*把当前节点的下一个节点赋给tmp */
cur->next=person->next; //若当前节点为原链表中的第一个节点,则使其next指向NULL
//否则使其next指向原链表中当前节点的上一个节点,也就是正在逆序中的第一个节点
person->next=cur; /*使头指针指向当前节点*/
cur=tmp; /*把原cur的下一个节点赋给cur*/
}
}
return(person);
}
void GetMid(stud *person) //获取中间节点的数据
{
stud *onestep,*twostep; //采用步进的策略,一个每次步进1,另一个每次步进2,这样当步进为2的指针指向的节点的next为空时,另一个指针刚好指向中间节点或者中间的第一个节点
if(N%2) //判断以决定采用的步进策略
{
onestep=twostep=person->next;
while(twostep->next!=NULL)
{
twostep=twostep->next->next;
onestep=onestep->next;
}
printf("\n处于中间位置的人只有一个,\n\t其名称为:%s,其年龄为:%d。\n\n",onestep->name,onestep->age);
}
else
{
onestep=twostep=person;
while(twostep->next!=NULL)
{
twostep=twostep->next->next;
onestep=onestep->next;
}
printf("\n处于中间位置的人有两个,\n\t第一个名称为:%s,其年龄为:%d;\n\t第二个名称为:%s,其年龄为:%d。\n\n",onestep->name,onestep->age,onestep->next->name,onestep->next->age);
}
}
void Print(stud *person)
{
int post=1;
stud *cur;
cur=person->next;
printf("当前的节点信息如下所示:\n");
while(cur!=NULL)
{
printf("第%d个人的姓名是:%s,年龄为:%d;\n",post,cur->name,cur->age);
cur=cur->next;
post++;
}
N=--post;
printf("当前单链表的长度是:%d。\n\n",N);
}
int main()
{
int number,post,i;
stud *head;
head=Create(N);
Print(head);
for(i=0;i<times;i++)
{
GetMid(head);
printf("请输入要删除的节点的位置:\n");
scanf("%d",&number);
Delete(head,number);
Print(head);
printf("请输入要插入节点的位置(此位置是指预期插入成功后新节点在单链表中的位置):\n");
scanf("%d",&post);
Insert(head,post);
Print(head);
printf("以下展示了两次单链表的逆序!!!\n\n");
Print(Reverse(head));
Print(Reverse(head));
printf("\n注意:剩余输入轮数为:%d !!!!!\n\n",(times-(i+1)));
}
return 0;
}
调试环境:Ubuntu Desktop 8.04.4 VI 7.1.138 GCC 4.2.4
QQ:81064483
E-mail:AllenNewOK@126.com
复习之用,不足之处,敬请指正。< ^_^ >
分享到:
相关推荐
在本主题中,"danlianbiao.rar_单链表的操作_链表降序" 提到了单链表的一系列操作,包括创建、查询、修改以及对链表进行特定的算法处理。下面我们将详细探讨这些知识点。 1. **建立单链表**:建立单链表通常从创建...
创建单链表通常从创建头节点开始,头节点不存储任何数据,仅用于链接其他节点。之后,我们可以按需添加节点到链表的末尾或特定位置。例如,创建一个空链表可以这样实现: ```c typedef struct Node { int data; ...
删除链表的中间节点和a/b处的节点 腕单向链表和链 部分单向链表 环形单链表的约瑟夫问题 一个鉴定链表是否为回文结构 将单向链某值分割成小表、送、按右边大的形式 复制带有日常指针的节点表 两个单链表生成相加链表...
本主题聚焦于顺序链表(单链表)的C语言实现,包括正序创建、逆序创建、输出、删除、插入节点、求链表长度以及合并链表等操作。 1. **链表的基本概念**:链表由一系列节点组成,每个节点包含数据和指向下一个节点的...
与数组不同,链表的元素在内存中不是连续存储的,这使得插入和删除操作相对高效,但随机访问效率较低。 在`SINGLY LL.cpp`这个文件中,我们可以预见到代码将实现以下功能: 1. **链表节点定义**:首先,会定义一个...
9. **计算链表长度**:通过遍历链表并计数节点数量来得到链表的长度。 10. **排序链表**:对于数值型链表,可以应用各种排序算法(如冒泡、插入、快速等)对其进行排序。 11. **分裂链表**:根据特定条件(例如,...
本篇文章将详细讲解C++中链表的基本操作,包括创建、计数、查找、输出、清空、逆序等。 首先,链表的节点结构定义如下: ```cpp struct Node{ int num; Node *next; }; ``` 其中,`num` 是节点存储的数据,`next`...
与数组不同,链表的元素(节点)在内存中并不是连续存储的,而是通过指针相互连接。这种灵活性使得链表在处理动态数据集合时具有显著优势。下面我们将详细探讨C语言中链表的基本操作。 1. **链表的定义** 在C语言...
总结起来,这篇文档涵盖了单链表的基本操作,包括创建、输出、计算长度、删除节点和倒序,以及二叉树的构建概念。这些是数据结构基础课程中的核心内容,对于理解计算机科学中的数据存储和处理至关重要。通过实际编程...
双循环链表是一种数据结构,它在单链表的基础上增加了一个前向指针,使得每个节点不仅知道下一个节点,还知道上一个节点。这在处理需要逆向遍历或者需要快速访问相邻节点的问题时非常有用。下面我们将深入探讨双循环...
总结来说,这个博客文章介绍了如何使用递归实现单向链表的基本操作,包括计数、打印、删除和查找元素。这些操作展示了递归思想在解决链表问题中的应用,同时也提醒我们在实际编程时需要权衡代码的简洁性和执行效率。
// 取得单链表中第i个节点地址,i从0开始计数,i时返回指针0,i=0时返回表头节点地址。 if (i ) return NULL; ListNode* p = first; int k = 0; while (p != NULL && k ) { p = p->link; k++; } return p; } ```...
3、查找单链表中第K个结点:在线性表中查找第K个元素是常见的操作。从头结点开始,按照链表的顺序遍历,每经过一个节点,计数器加1,当计数器等于K时,找到的节点就是第K个结点。需要注意的是,这里的K是从1开始计数...
8. 顺序表的移动次数:插入和删除操作平均需要移动n/2个节点,具体移动次数取决于插入或删除的位置以及表的当前状态。 9. 栈的序列操作:栈具有后进先出(LIFO)特性,根据这个性质,可以判断哪些序列是可能的出栈...
链表的逆序是指将链表中的节点逆序排列。下面是一个简单的链表逆序示例代码: ```cpp Node *ReverseList(Node *head) { Node *p, *q, *r; p = head; q = p->next; while (q != NULL) { r = q->next; q->next =...
初始化:创建单链表,包括排长节点及其后的第一个士兵节点。 2. 插入节点:依次插入剩余的士兵节点,并设置它们的`data`值。 3. 执行任务:从第一个节点开始计数,每数到5则选出一名士兵执行任务,并输出该士兵的...
9. **单链表的逆序**:链表是数据结构的一种,逆序操作可以改变链表节点的顺序。逆序链表需要遍历整个链表,创建新的指针关系,并最终更新头指针。 这些算法和数据结构是计算机科学的基础,对于理解程序设计和优化...
栈方法则是将链表的所有节点压入栈中,然后逐个弹出并打印,栈的特性使得最后压入的节点最先弹出,从而达到逆序输出的效果。 2. 二叉树的深度计算: 二叉树的深度是指从根节点到最远叶节点的最长路径上的边数。...
查找、插入和删除操作的时间复杂度均摊为O(log n)。 5. **AVL树** 和 **红黑树** 是两种特殊的二叉搜索树,通过特定的平衡规则确保查找效率。 6. **B树** 和 **B+树** 适用于大型数据存储,如数据库索引,支持高效...