不带头结点的单链表表中交换两个相邻结点位置

用心创造滤镜
扫码下载App
汇聚2000万达人的兴趣社区下载即送20张免费照片冲印
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
struct node
struct node *
二、定义每个结点有学号和分数以及指向下一个结点的指针,现在想写一个creat_nod能够创建一个结点,希望它带num和score两个参数,创建完毕以后直接返回该结点结构体类型指针。
struct node *creat_nod(int x,int y)
struct node *p;&
& & & & p =
p-&score =
三、删除某个结点,希望直接给定链表head以及学号,就删除特定学号结点,这里有3种情况,表头,表尾和表中。
1、表头情形,将第二个结点升为头结点,head=head-&释放头结点存储空间。&
2、表中与表尾情形类似,直接删除,将自己指向下一个的地址传给上一个结点,表尾时传的是NULL。
struct node *del_nod(node *n_head,int x)
& &struct node *p,*q;
& &if(n_head==NULL) cout&&"链表为空!";//排除特殊情形
& while(p!=NULL&&p-&num!=x) {q=p;p=p-&}//找到要删的结点位置
& & & &if(p==n_head) {n_head=p-&}//删除头结点情形
& else if(p!=NULL) {q-&next=p-&}
else cout&&x&&"不在链表中!";
& &return n_
四、插入某个结点,希望链表根据学号予以排序,也分3种情形,表头、表尾和表中。
1、表头情形下,插入节点变成表头,先将表头地址给新结点的next,再将新结点地址赋给表头。
2、表尾情形下,先将新结点地址赋给表尾next,再将新结点的next置空。新结点成了尾节点。
3、表中情形下,新结点地址给前一个结点的next,新结点的next指向下一个结点。
struct node *insert_nod(node *n_head,int x,int y)
struct node *p,*q,*n_
n_nod-&num=x;
n_nod-&score=y;
if(n_head==NULL) {n_head=n_n_nod-&next=NULL;}//排除特殊情形
while(p!=NULL&&x&p-&num)
}//找到插入点
if(p==n_head){n_nod-&next=n_n_head=n_}//插入头结点之前的情形
else if(p==NULL){q-&next=n_n_nod-&next=NULL;}
& & &q-&next=n_n_nod-&next=p;
五、给一个头指针,即可打印所有结点,需要遍历每个结点。
void print_nod(node *w)
& & struct node *p;
if(w=NULL) cout&&"链表为空!";
while(p!=NULL)
cout&&"学号:"&&p-&num&&setw(10)&&"分数:"&&p-&score&&
六、根据头指针和学号能够查找相应结点并输出成绩。
void search_nod(node *w,int x)
struct node *p;
while(p!=NULL&&p-&num!=x)
if(p==NULL) cout&&"您找的学号不存在!";
else print_nod(p);
七、链表的逆序,我希望只给一个头指针就能实现逆序功能,注意交换指针时要注意保存指向下一个结点的指针。
struct node *reverse_nod(node *n_head){&struct node *p,*q,*t;&&int i=0;&p=n_&if(n_head==NULL) cout&&"链表为空!";&else&{&&while(t!=NULL)&&{&&&if(i==0){&&&&q=p;&&&&p=p-&&&&&&&&q-&next=NULL;&&&&t=p-&&&&&p-&next=q;&&&&&&&i++;&&&}//开头的情形,需要将头结点的next清空&&&else &&&&{&&&&&q=p;&&&&&p=t;&&&&&t=p-&&&&&&p-&next=q;&&&&}&&}&&&n_head=p;&&}
&return n_
八、下面写一个主函数测试它们。
int main()
struct node *head,*stu1,*stu2,*stu3;
num=1170381;
head=creat_nod(num,score);
num=1170382;
stu1=creat_nod(num,score);
num=1170384;
stu2=creat_nod(num,score);
num=1170385;
stu3=creat_nod(num,score);
head-&next=stu1;
stu1-&next=stu2;
stu2-&next=stu3;
stu3-&next=NULL;//创建了一个4个结点的链表
head=insert_nod(head,);
& & head=insert_nod(head,);
head=insert_nod(head,);
print_nod(head);//插入3个结点并打印
head=del_nod(head,1170380);
head=del_nod(head,1170383);
head=del_nod(head,1170386);
print_nod(head);
cout&&//删除插入的结点
cout&&"请输入您查找的学号:";
search_nod(head,num);//查找指定结点并打印
运行结果:
主函数加入该行:&
head=reverse_nod(head);&print_nod(head);&运行结果为:
上面为正序,下面为逆序。&
阅读(2460)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'一个C++程序完成链表的增加结点、删除结点、打印、查询、逆序等操作',
blogAbstract:'
一、每个结点结构体声明如下,注意该链表是不带表头的单链表:
struct node
struct node *
二、定义每个结点有学号和分数以及指向下一个结点的指针,现在想写一个creat_nod能够创建一个结点,希望它带num和score两个参数,创建完毕以后直接返回该结点结构体类型指针。
struct node *creat_nod(int x,int y)
struct node *p;&
& & & & p =
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:5,
publishTime:8,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:1,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}数据结构答案 第2章 线性表学习指导_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
数据结构答案 第2章 线性表学习指导
上传于||文档简介
&&数​据​结​构​答​案
阅读已结束,如果下载本文需要使用
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩6页未读,继续阅读
你可能喜欢链表(二)――单向链表的基本操作(创建、删除、打印、结点个数统计)
1.指针的联动
通过两个指针分别指向前驱和后继结点,并在单向链表上进行移动,当指针指向待处理的结点时,该结点的前驱也有指针指向。
2.设有一个无序单向链表,且数据域的值均不相同,使指针pmin指向最小值结点,并使指针prem指向最小值结点的前驱结点:
代码片段:
for(p = q = p, p = p->next)
if(pmin->data > p->data)
3.单向链表的删除算法
注:使用malloc函数分配的结点单元必须使用free函数来释放,free(p)之后,p所指向的单元被释放,p被重新赋值为随机值,p只能在程序运行完成之后自动清除。
头结点的删除:head = head->free(pdel);
非头结点的删除:ppre->next = pdel->free(pdel);
注:单向链表的最基本的操作,新建一个链表、删除一个元素、打印链表、统计链表的个数、删除链表。
#define NULL 0
typedef struct node {
struct node *
ElemSN * creat_link(int ms); //逆向创建一个链表
void print_link(ElemSN *head); //输出单向链表
ElemSN * delete_node(ElemSN *head, int x); //删除链表中的一个结点
int count_link(ElemSN *head); //统计单向链表结点的个数
ElemSN * clear_link(ElemSN *head); //删除链表
int main()
printf("Please input node number:");
scanf("%d", &ms);
head = creat_link(ms);
print_link(head);
printf("Please input delete node:");
scanf("%d", &x);
head = delete_node(head, x);
print_link(head);
printf("link member is :%d\n", count_link(head));
head = clear_link(head);
ElemSN * creat_link(int ms)
ElemSN *h = NULL, *p;
for(i = 0; i data =
void print_link(ElemSN *head)
for(; head = head->next)
printf("%d ", head->data);
printf("\n");
ElemSN * delete_node(ElemSN *head, int x)
ElemSN *p = NULL, *q = NULL;
if(NULL == head)
return NULL;
for(p = p && p->data != q = p, p = p->next); //p && p->data != x不能交换位置
if(NULL == p) //没有找到要删除的结点
if(NULL == q) //要删除的是头结点
head = head->
q->next = p->
int count_link(ElemSN *head)
int count = 0;
for(; count++, head = head->next);
ElemSN * clear_link(ElemSN *head)
ElemSN *p;
while(head)
p = head->
free(head);比较两种思路的差异
服务器君一共花费了72.211 ms进行了3次数据库查询,努力地为您提供了这个页面。
试试阅读模式?希望听取您的建议
究竟要如何呢?我们不妨拿一个例子来说明一下算法。
第一次交换
第二次交换
第三次交换
定义当前结点 current,初始值为首元结点,current = L->
定义当前结点的后继结点 pnext, pnext = current->
只要 pnext 存在,就执行以下循环:
定义新节点 prev,它是 pnext的后继结点,prev = pnext->
把pnext的后继指向current, pnext->next =
此时,pnext 实际上已经到了 current 前一位成为新的current,所以这个时候 current 结点实际上成为新的 pnext,current =
此时,新的 current 就是 pnext,current =
而新的 pnext 就是 prev,pnext =
最后将头结点与 current 重新连上即可,L->next =
函数设计如下:
/* 单链表反转/逆序 */
Status ListReverse(LinkList L)
LinkList current,pnext,
if(L == NULL || L->next == NULL)
current = L->
/* p1指向链表头节点的下一个节点 */
pnext = current->
current->next = NULL;
while(pnext)
prev = pnext->
pnext->next =
printf("交换后:current = %d,next = %d \n",current->data,current->next->data);
//printf("current = %d,next = %d \n",current->data,current->next->data);
/* 将链表头节点指向p1 */
Status ListReverse2(LinkList L)
LinkList current,
if (L == NULL)
return NULL;
current = L->
while (current->next != NULL)
p = current->
current->next = p->
p->next = L->
p = current-> p 就相当于前面的 pnext。(图1中a2即为p)
current->next = p-> p->next 就相当于 prev的角色,这句代码意思是 current 的后继指向 prev.(相当于图1中a1->next = a3(a2->next))
p->next = L-> 这句就是 p 的后继直接指向首元节点。(相当于图1中a2->next = a1)
L->next = 然后再将头结点指向 p。(相当于图1中L->next = a2)
这个是程序运行的结果。
整体创建L的元素(头插法):
// 原链表,current = 68, pnext = 55,68指向18,55指向18,头结点指向55
-> 68 -> 55 -> 18 -> 45 -> 41 -> 43 -> 5 -> 28 -> 80 -> 67
// 第一次交换后,原链表变成这样
-> 55 -> 68 -> 18 -> 45 -> 41 -> 43 -> 5 -> 28 -> 80 -> 67
// 进行第二次交换,pnext = 18,68指向45,18变成头结点
-> 18 -> 55 -> 68 -> 45 -> 41 -> 43 -> 5 -> 28 -> 80 -> 67
// 进行第三次交换,pnext = current->next = 45,68指向41,45变成头结点
-> 45 -> 18 -> 55 -> 68 -> 41 -> 43 -> 5 -> 28 -> 80 -> 67
-> 41 -> 45 -> 18 -> 55 -> 68 -> 43 -> 5 -> 28 -> 80 -> 67
-> 43 -> 41 -> 45 -> 18 -> 55 -> 68 -> 5 -> 28 -> 80 -> 67
-> 5 -> 43 -> 41 -> 45 -> 18 -> 55 -> 68 -> 28 -> 80 -> 67
-> 28 -> 5 -> 43 -> 41 -> 45 -> 18 -> 55 -> 68 -> 80 -> 67
-> 80 -> 28 -> 5 -> 43 -> 41 -> 45 -> 18 -> 55 -> 68 -> 67
// current 68 没有后继,反转结束
-> 67 -> 80 -> 28 -> 5 -> 43 -> 41 -> 45 -> 18 -> 55 -> 68
-> 67 -> 80 -> 28 -> 5 -> 43 -> 41 -> 45 -> 18 -> 55 -> 68
最后附上完整代码,反转有两个函数。
方法1,current始终保持在第一位,pnext与prev遍历并完成交换。
方法2,current始终是原链表的第一个数,然后把pnext不断移动到首位。
#include "stdio.h"
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int S/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemT/* ElemType类型根据实际情况而定,这里假设为int */
typedef struct Node
struct Node *
/* 定义LinkList */
typedef struct Node *LinkL
/* 初始化顺序线性表 */
Status InitList(LinkList *L)
*L=(LinkList)malloc(sizeof(Node)); /* 产生头结点,并使L指向此头结点 */
if(!(*L)) /* 存储分配失败 */
return ERROR;
(*L)->next=NULL; /* 指针域为空 */
return OK;
/* 初始条件:顺序线性表L已存在。操作结果:返回L中数据元素个数 */
int ListLength(LinkList L)
LinkList p=L-> /* p指向第一个结点 */
/* 初始条件:顺序线性表L已存在。操作结果:将L重置为空表 */
Status ClearList(LinkList *L)
LinkList p,q;
p指向第一个结点 */
没到表尾 */
(*L)->next=NULL;
/* 头结点指针域为空 */
return OK;
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
Status ListTraverse(LinkList L)
LinkList p=L->
visit(p->data);
printf("\n");
return OK;
Status visit(ElemType c)
printf("-> %d ",c);
return OK;
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:用e返回L中第i个数据元素的值 */
Status GetElem(LinkList L,int i,ElemType *e)
/* 声明一结点p */
/* 让p指向链表L的第一个结点 */
j为计数器 */
while (p && j
/* 让p指向下一个结点 */
if ( !p || j>i )
return ERROR;
第i个元素不存在 */
取第i个元素的数据 */
return OK;
/* 初始条件:顺序线性表L已存在 */
/* 操作结果:返回L中第1个与e满足关系的数据元素的位序。 */
/* 若这样的数据元素不存在,则返回值为0 */
int LocateElem(LinkList L,ElemType e)
LinkList p=L->
if(p->data==e) /* 找到这样的数据元素 */
随机产生n个元素的值,建立带表头结点的单链线性表L(头插法) */
void CreateListHead(LinkList *L, int n)
srand(time(0));
/* 初始化随机数种子 */
*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;
先建立一个带头结点的单链表 */
for (i=0; i data = rand()%100+1;
随机生成100以内的数字 */
p->next = (*L)->
(*L)->next =
插入到表头 */
随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail(LinkList *L, int n)
LinkList p,r;
srand(time(0));
/* 初始化随机数种子 */
*L = (LinkList)malloc(sizeof(Node)); /* L为整个线性表 */
/* r为指向尾部的结点 */
for (i=0; i data = rand()%100+1;
随机生成100以内的数字 */
r->next=p;
/* 将表尾终端结点的指针指向新结点 */
/* 将当前的新结点定义为表尾终端结点 */
r->next = NULL;
/* 表示当前链表结束 */
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L), */
/* 操作结果:在L中第i个位置之前插入新的数据元素e,L的长度加1 */
Status ListInsert(LinkList *L,int i,ElemType e)
LinkList p,s;
/* 声明一个结点 p,指向头结点 */
while (p && j
if (!p || j > i)
return ERROR;
/* 第i个元素不存在 */
s = (LinkList)malloc(sizeof(Node));
生成新结点(C语言标准函数) */
s->next = p->
/* 将p的后继结点赋值给s的后继
/* 将s赋值给p的后继 */
return OK;
/* 初始条件:顺序线性表L已存在,1≤i≤ListLength(L) */
/* 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1 */
Status ListDelete(LinkList *L,int i,ElemType *e)
LinkList p,q;
while (p->next && j
if (!(p->next) || j > i)
return ERROR;
/* 第i个元素不存在 */
p->next = q->
/* 将q的后继赋值给p的后继 */
/* 将q结点中的数据给e */
/* 让系统回收此结点,释放内存 */
return OK;
/* 单链表反转/逆序 */
Status ListReverse(LinkList L)
LinkList current,pnext,
if(L == NULL || L->next == NULL)
current = L->
/* p1指向链表头节点的下一个节点 */
pnext = current->
current->next = NULL;
while(pnext)
prev = pnext->
pnext->next =
//printf("current = %d,next = %d \n",current->data,current->next->data);
/* 将链表头节点指向p1 */
Status ListReverse2(LinkList L)
LinkList current,
if (L == NULL)
return NULL;
current = L->
while (current->next != NULL)
p = current->
current->next = p->
p->next = L->
ListTraverse(L);
printf("current = %d, \n", current -> data);
int main()
LinkList L;
int j,k,pos,
i=InitList(&L);
printf("链表L初始化完毕,ListLength(L)=%d\n",ListLength(L));
printf("\n1.整表创建(头插法) \n2.整表创建(尾插法) \n3.遍历操作 \n4.插入操作");
printf("\n5.删除操作 \n6.获取结点数据 \n7.查找某个数是否在链表中 \n8.置空链表");
printf("\n9.链表反转逆序");
printf("\n0.退出 \n请选择你的操作:\n");
while(opp != '0'){
scanf("%c",&opp);
switch(opp){
CreateListHead(&L,10);
printf("整体创建L的元素(头插法):\n");
ListTraverse(L);
printf("\n");
CreateListTail(&L,10);
printf("整体创建L的元素(尾插法):\n");
ListTraverse(L);
printf("\n");
ListTraverse(L);
printf("\n");
printf("要在第几个位置插入元素?");
scanf("%d",&pos);
printf("插入的元素值是多少?");
scanf("%d",&value);
ListInsert(&L,pos,value);
ListTraverse(L);
printf("\n");
printf("要删除第几个元素?");
scanf("%d",&pos);
ListDelete(&L,pos,&e);
printf("删除第%d个元素成功,现在链表为:\n", pos);
ListTraverse(L);
printf("\n");
printf("你需要获取第几个元素?");
scanf("%d",&pos);
GetElem(L,pos,&e);
printf("第%d个元素的值为:%d\n", pos, e);
printf("\n");
printf("输入你需要查找的数:");
scanf("%d",&pos);
k=LocateElem(L,pos);
printf("第%d个元素的值为%d\n",k,pos);
printf("没有值为%d的元素\n",pos);
printf("\n");
i=ClearList(&L);
printf("\n清空L后:ListLength(L)=%d\n",ListLength(L));
ListTraverse(L);
printf("\n");
ListReverse2(L);
printf("\n反转L后\n");
ListTraverse(L);
printf("\n");
延伸阅读此文章所在专题列表如下:
本文地址:,欢迎访问原出处。
不打个分吗?
转载随意,但请带上本文地址:
如果你认为这篇文章值得更多人阅读,欢迎使用下面的分享功能。
小提示:您可以按快捷键 Ctrl + D,或点此 。
大家都在看
现代魔法研究协会欢迎你
阅读一百本计算机著作吧,少年
Noab Gift (作者), Jeremy M.Jones (作者)
《Python在Unix和Linux系统管理中的应用(影印版)》作者们还构建了一个可以免费下载的Ubuntu虚拟机。该虚拟机包含了这《Python在Unix和Linux系统管理中的应用(影印版)》的源代码,还可以用来运行书中的实例,包括SNMP、IPython、SQLAlchemy和许多其他工具。《Python在Unix和Linux系统管理中的应用》展示了Python语言如何提供一种更加高效的方式来处理Unix和Linux服务器管理工作中的各种任务。《Python在Unix和Linux系统管理中的应用(影印版)》的每一章都会提出一个特定的管理问题,例如并发或数据备份,然后通过实际的例子提供基于Python的解决方案。
扫一扫,在手机上阅读
栏目最新博文
7,575 views
8,310 views
4,119 views
3,499 views
7,647 views
8,757 views
6,075 views
5,431 views
4,663 views
10,825 views
栏目博文推荐
13,722 views
8,174 views
4,523 views
13,832 views
5,754 views
5,204 views
8,009 views
7,836 views
9,778 views
10,663 views
帮助别人,就是帮助自己。
关于网站与作者
互联网信息太多太杂,各互联网公司不断推送娱乐花边新闻,SNS,微博不断转移我们的注意力。但是,我们的时间和精力却是有限的。这里是互联网浩瀚的海洋中的一座宁静与美丽的小岛,供开发者歇息与静心潜心修炼(愿景)。
“Veda”的本义是知识、启示,希望这里能为开发者提供充足的技术资料。
我的电子邮件gonnsai(,腾讯微博:,欢迎与我联系。带头结点的单链表中交换两个相邻结点位置_百度知道
带头结点的单链表中交换两个相邻结点位置
麻烦要相对简练的代码
无可抗拒他的魅力了,没想到啊,我想看看他还有什么来吸引我
额,白高兴一场,不带这样糊弄人的
其他类似问题
为您推荐:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 不带头结点单链表 的文章

 

随机推荐