王为民的技术和生活空间

练内功、勤实战、学习数学、迸发创新意识、注重团队精神,把握好前进的方向…………

用户操作
[即时聊天] [发私信] [加为好友]
王为民ID:ningboweimin
93346次访问,排名1066,好友17人,关注者23人。
08.05-至今 深圳清华力合通信有限公司 MMI开发
07.09--08.05 深圳胜博联技术有限公司 MTK MMI开发。
05.12-07.08 宁波高凌通信技术有限公司工作,主要负责双膜(GSM/PHS)手机及小灵通的研究和开发,平台涉及展讯及东芝。
05.6-05.12 国家数字交换系统工程技术研究中心(NDSC) 主要从事路由器路由协议调试和开发,具体负责多协议标志交换(MPLS)模块,深入了解了其信令和控制协议——标记分发协议(LDP)。
ningboweimin的文章
原创 104 篇
翻译 1 篇
转载 105 篇
评论 18 篇
王为民的公告
清新家园

关注C语言,关注生活。 QQ:94686732 Msn:wwmzxy@hotmail.com
wangweiminxy@gmail.com
XING
最近评论
sap99:www.sap99.com/,SAP99资料多多

SAP免费资料下载
http://www.sap99.com

有很多的学习资料,推荐一下,
ningboweimin:自己顶下先。。。
wuqifeng0101:你好 不知道你能不能提供信大微电子专业的专业课试题数字电路和微机原理 谢谢!
wangseaya:真是幸福的一对啊
羡慕ing
祝福ing
sunag:天仙配
羡慕
嫂子真漂亮
吼吼
不过呢
你有点胖了
尤其是肚子
要多运动啊
文章分类
收藏
相册
户外婚礼
美丽风景
我和朋友
行网聚会
IT技术
IBM技术专家群
ITPUB
MSDN中国
VC知识库
中国Unix技术
中国系统分析师
嵌入式资讯网
红联LINUX
计算机世界
软件工程专家网
管理天地
IT经理世界
华尔街日报
好书阁
《华为真相》
《商道》
《墨迹》
《没有任何借口》
《细节决定成败》
朋友圈
My Gallery
XING宁波
军华
冰儿
可爱狼
小潘
嵐曦一尘
月光博客
朗朗星空
梅花三弄
永超
江涛
瀚海星尘
程军剑
管为为
胡雪儿
馨荣家园
网络通信
Cisco网络技术
中国3G通信网
中国协议分析网
中国通信资源网
休闲娱乐
Google黑板报
Mofile TV
人民网
英语学习网
行网中国
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 有关双向链表的一点探讨--C语言版收藏

新一篇: 精彩的手机壁纸--个人收集 | 旧一篇: 浅析malloc()的几种实现方式

 有关双向链表的一点探讨--C语言版

       链表是C语言和数据结构中比较重要的结构体,大致分为线性链表,环形链表,双向或双重链表,环形双向链表等。这里着重介绍双向链表。在说明双向链表前,先简单介绍一下循环链表。

  循环链表是与单链表一样,是一种链式的存储结构,所不同的是,循环链表的最后一个结点的指针是指向该循环链表的第一个结点或者表头结点,从而构成一个环形的链。

  循环链表的运算与单链表的运算基本一致。所不同的有以下几点:

  1、在建立一个循环链表时,必须使其最后一个结点的指针指向表头结点,而不是象单链表那样置为NULL。此种情况还使用于在最后一个结点后插入一个新的结点。

  2、在判断是否到表尾时,是判断该结点链域的值是否是表头结点,当链域值等于表头指针时,说明已到表尾。而非象单链表那样判断链域值是否为NULL。

  双向链表

  双向链表其实是单链表的改进。

  当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。

  在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。在c语言中双向链表结点类型可以定义为:


typedef struct node
{
int data; /*数据域*/
struct node *llink,*rlink; /*链域,*llink是左链域指针,*rlink是右链域指针*/
}JD;


  当然,也可以把一个双向链表构建成一个双向循环链表。

  双向链表与单向链表一样,也有三种基本运算:查找、插入和删除。

  双向链表的基本运算:

  1、查找

  假若我们要在一个带表头的双向循环链表中查找数据域为一特定值的某个结点时,我们同样从表头结点往后依次比较各结点数据域的值,若正是该特定值,则返回指向结点的指针,否则继续往后查,直到表尾。

  下例就是应用双向循环链表查找算法的一个程序。

#include <stdio.h>
#include <malloc.h>
#define N 10

typedef struct node
{
 char name[20];
 struct node *llink,*rlink;
}stud;

stud * creat(int n)
{
 stud *p,*h,*s;
 int i;
 if((h=(stud *)malloc(sizeof(stud)))==NULL)
 {
  printf("不能分配内存空间!");
  exit(0);
 }
 h->name[0]=’\0’;
 h->llink=NULL;
 h->rlink=NULL;
 p=h;
 for(i=0;i<n;i++)
 {
  if((s= (stud *) malloc(sizeof(stud)))==NULL)
  {
   printf("不能分配内存空间!");
   exit(0);
  }
  p->rlink=s;
  printf("请输入第%d个人的姓名",i+1);
  scanf("%s",s->name);
  s->llink=p;
  s->rlink=NULL;
  p=s;
 }
 h->llink=s;
 p->rlink=h;
 return(h);
}

stud * search(stud *h,char *x)
{
 stud *p;
 char *y;
 p=h->rlink;
 while(p!=h)
 {
  y=p->name;
  if(strcmp(y,x)==0)
   return(p);
  else p=p->rlink;
 }
 printf("没有查找到该数据!");
}

void print(stud *h)
{
 int n;
 stud *p;
 p=h->rlink;
 printf("数据信息为:\n");
 while(p!=h)
 {
  printf("%s ",&*(p->name));
  p=p->rlink;
 }
 printf("\n");
}

main()
{
 int number;
 char studname[20];
 stud *head,*searchpoint;
 number=N;
 clrscr();
 head=creat(number);
 print(head);
 printf("请输入你要查找的人的姓名:");
 scanf("%s",studname);
 searchpoint=search(head,studname);
 printf("你所要查找的人的姓名是:%s",*&searchpoint->name);
}

2、插入

  对于双向循环链表,我们现在可以随意地在某已知结点p前或者p后插入一个新的结点。

  假若s,p,q是连续三个结点的指针,若我们要在p前插入一个新结点r,则只需把s的右链域指针指向r,r的左链域指针指向s,r的右链域指针指向p,p的左链域指针指向r即可。

  在p,q之间插入原理也一样。

  下面就是一个应用双向循环链表插入算法的例子:

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define N 10

typedef struct node
{
 char name[20];
 struct node *llink,*rlink;
}stud;

stud * creat(int n)
{
 stud *p,*h,*s;
 int i;
 if((h=(stud *)malloc(sizeof(stud)))==NULL)
 {
  printf("不能分配内存空间!");
  exit(0);
 }
 h->name[0]=’\0’;
 h->llink=NULL;
 h->rlink=NULL;
 p=h;
 for(i=0;i<n;i++)
 {
  if((s= (stud *) malloc(sizeof(stud)))==NULL)
  {
   printf("不能分配内存空间!");
   exit(0);
  }
  p->rlink=s;
  printf("请输入第%d个人的姓名",i+1);
  scanf("%s",s->name);
  s->llink=p;
  s->rlink=NULL;
  p=s;
 }
 h->llink=s;
 p->rlink=h;
 return(h);
}

stud * search(stud *h,char *x)
{
 stud *p;
 char *y;
 p=h->rlink;
 while(p!=h)
 {
  y=p->name;
  if(strcmp(y,x)==0)
   return(p);
  else p=p->rlink;
 }
 printf("没有查找到该数据!");
}

void print(stud *h)
{
 int n;
 stud *p;
 p=h->rlink;
 printf("数据信息为:\n");
 while(p!=h)
 {
  printf("%s ",&*(p->name));
  p=p->rlink;
 }
 printf("\n");
}

void insert(stud *p)
{
 char stuname[20];
 stud *s;
 if((s= (stud *) malloc(sizeof(stud)))==NULL)
 {
  printf("不能分配内存空间!");
  exit(0);
 }
 printf("请输入你要插入的人的姓名:");
 scanf("%s",stuname);
 strcpy(s->name,stuname);
 s->rlink=p->rlink;
 p->rlink=s;
 s->llink=p;
 (s->rlink)->llink=s;
}

main()
{
 int number;
 char studname[20];
 stud *head,*searchpoint;
 number=N;
 clrscr();
 head=creat(number);
 print(head);
 printf("请输入你要查找的人的姓名:");
 scanf("%s",studname);
 searchpoint=search(head,studname);
 printf("你所要查找的人的姓名是:%s\n",*&searchpoint->name);
 insert(searchpoint);
 print(head);
}

3、删除

  删除某个结点,其实就是插入某个结点的逆操作。还是对于双向循环链表,要在连续的三个结点s,p,q中删除p结点,只需把s的右链域指针指向q,q的左链域指针指向s,并收回p结点就完成了。

  下面就是一个应用双向循环链表删除算法的例子:

#include
#include
#include
#define N 10

typedef struct node
{
 char name[20];
 struct node *llink,*rlink;
}stud;

stud * creat(int n)
{
 stud *p,*h,*s;
 int i;
 if((h=(stud *)malloc(sizeof(stud)))==NULL)
 {
  printf("不能分配内存空间!");
  exit(0);
 }
 h->name[0]=’\0’;
 h->llink=NULL;
 h->rlink=NULL;
 p=h;
 for(i=0;i〈n;i++)
 {
  if((s= (stud *) malloc(sizeof(stud)))==NULL)
  {
   printf("不能分配内存空间!");
   exit(0);
  }
  p-〉rlink=s;
  printf("请输入第%d个人的姓名",i+1);
  scanf("%s",s->name);
  s->llink=p;
  s->rlink=NULL;
  p=s;
 }
 h->llink=s;
 p->rlink=h;
 return(h);
}

stud * search(stud *h,char *x)
{
 stud *p;
 char *y;
 p=h->rlink;
 while(p!=h)
 {
  y=p->name;
  if(strcmp(y,x)==0)
   return(p);
  else p=p->rlink;
 }
 printf("没有查找到该数据!");
}

void print(stud *h)
{
 int n;
 stud *p;
 p=h->rlink;
 printf("数据信息为:\n");
 while(p!=h)
 {
  printf("%s ",&*(p->name));
  p=p->rlink;
 }
 printf("\n");
}

void del(stud *p)
{
 (p->rlink)->llink=p->llink;
 (p->llink)->rlink=p->rlink;
 free (p);
}

main()
{
 int number;
 char studname[20];
 stud *head,*searchpoint;
 number=N;
 clrscr();
 head=creat(number);
 print(head);
 printf("请输入你要查找的人的姓名:");
 scanf("%s",studname);
 searchpoint=search(head,studname);
 printf("你所要查找的人的姓名是:%s\n",*&searchpoint->name);
 del(searchpoint);
 print(head);
}

 

 

发表于 @ 2007年07月13日 10:44:00|评论(loading...)|编辑

新一篇: 精彩的手机壁纸--个人收集 | 旧一篇: 浅析malloc()的几种实现方式

评论:没有评论。

发表评论  


当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
Csdn Blog version 3.1a
Copyright © 王为民