c语言链表详细问题 动态链表好难理解 求画图或者详细解释

&&/&&&&/&&
在【例7-8】中采用了动态分配的办法为一个结构分配内存空间。每一次分配一块空间可用来存放一个学生的数据,我们可称之为一个结点。有多少个学生就应该申请分配多少块内存空间,也就是说要建立多少个结点。当然用结构数组也可以完成上述工作,但如果预先不能准确把握学生人数,也就无法确定数组大小。而且当学生留级、退学之后也不能把该元素占用的空间从数组中释放出来。
用动态存储的方法可以很好地解决这些问题。有一个学生就分配一个结点,无须预先确定学生的准确人数,某学生退学,可删去该结点,并释放该结点占用的存储空间。从而节约了宝贵的内存资源。另一方面,用数组的方法必须占用一块连续的内存区域。而使用动态分配时,每个结点之间可以是不连续的(结点内是连续的)。结点之间的联系可以用指针实现。 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。
可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为0。这样一种连接方式,在数据结构中称为&链表&。
下图为最一简单链表的示意图。
图中,第0个结点称为头结点,它存放有第一个结点的首地址,它没有数据,只是一个指针变量。以下的每个结点都分为两个域,一个是数据域,存放各种实际的数据,如学号num,姓名name,性别sex和成绩score等。另一个域为指针域,存放下一结点的首地址。链表中的每一个结点都是同一种结构类型。
例如,一个存放学生学号和成绩的结点应为以下结构:
struct stu{
struct stu *
前两个成员项组成数据域,后一个成员项next构成指针域,它是一个指向stu类型结构的指针变量。
链表的基本操作对链表的主要操作有以下几种:
建立链表;
结构的查找与输出;
插入一个结点;
删除一个结点。
下面通过例题来说明这些操作。
【例11-9】建立一个三个结点的链表,存放学生数据。为简单起见, 我们假定学生数据结构中只有学号和年龄两项。可编写一个建立链表的函数creat。程序如下:
#define NULL 0
#define TYPE struct stu
#define LEN sizeof (struct stu)
struct stu{
struct stu *
TYPE *creat(int n){
struct stu *head,*pf,*
for(i=0;i&n;i++){
pb=(TYPE*) malloc(LEN);
printf(&input Number and
scanf(&%d%d&,&pb-&num,&pb-&age);
if(i==0) pf=head=
else pf-&next=
pb-&next=NULL;
return(head);
在函数外首先用宏定义对三个符号常量作了定义。这里用 TYPE表示struct stu,用LEN表示sizeof(struct stu)主要的目的是为了在以下程序内减少书写并使阅读更加方便。结构stu定义为外部类型,程序中的各个函数均可使用该定义。
creat函数用于建立一个有n个结点的链表,它是一个指针函数,它返回的指针指向stu结构。在creat函数内定义了三个stu结构的指针变量。head为头指针,pf为指向两相邻结点的前一结点的指针变量。pb为后一结点的指针变量。
推荐文章 TOP10温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
本人性格开朗,善结交朋友。主要职业发展方向IT和电子行业!
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
算法本身没有什么特别的地方,为什么说这是一个通用双向链表呢?奥妙就在那四个 用于扩展的宏。利用这几个宏你可以将这个双向链表扩展到任意结构。例如,我们要实现一个消息队列,那么我们可以这样定义消息节点:typedef&struct&tagMSGNODE&{&&&&DECLARELISTNODE();&&&&HWND&&&&&&&&hW&&&&UINT&&&&&&&&uM&&&&WPARAM&&&&&&wP&&&&LPARAM&&&&&&lP}&MSGNODE,&*LPMSGNODE;而消息队列则可以直接用LISTNODE结构来表示:STDLIST&&&&&lstMsgQ这样我们就可以用刚刚定义的函数来对这个消息队列进行操作了://&向消息队列插入一个消息LPMSGNODE&lpMsgNode&=&MemAlloc(SIZEOF(MSGNODE));lpMsgNode-&INIT_LISTNODE();lpMsgNode-&hWnd&&&&&=&hWlpMsgNode-&uMsg&&&&&=&WM_PAINT;lpMsgNode-&wParam&&&=&NULL;lpMsgNode-&lParam&&&=&NULL;StdListPushBack(&lstMsgQueue,&(LPSTDNODE)lpMsgNode);//&从消 息队列取出一个消息LPMSGNODE&lpMsgNode&=&(LPMSGNODE)StdListPopFront(&lstMsgQueue);//&删除所有属于hWnd的消息LPMSGNODE&lpTemp&&&&=&(LPMSGNODE)StdListGetHeadNode(&lstMsgQueue);while(lpTemp)&{&&&&LPMSGNODE&lpNext&&&&=&(LPMSGNODE)StdListGetNextNode(&lstMsgQueue,&(LPSTDNODE)lpTemp);&&&&if(lpTemp-&hWnd&==&hWnd) {&&&&&&&&StdListRemove(&lstMsgQueue,&(LPSTDNODE)lpTemp);&&&&&&&&&&&&&&&&MemFree(lpTemp);&&&&&&&&}&&&&lpTemp&&=&lpN}是不是很方便呢^_^。&备注:由于正在编写的GUI是参考Windows的体系结构,所以代码风 格采用了微软的风格。代码中的MemAlloc,MemFree函数以及各种数据结构均 在其他地方定义
阅读(18793)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_',
blogTitle:'双向链表(C语言)详解 及 例程',
blogAbstract:'双(向)链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域prior。双向链表在查找时更方便 特别是大量数据的遍历',
blogTag:'c语言,双向链表',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:8,
publishTime:8,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:2,
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:'本人性格开朗,善结交朋友。主要职业发展方向IT和电子行业!',
hmcon:'1',
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}

我要回帖

更多关于 c语言链表 的文章

 

随机推荐