动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
电脑书籍下载:程序设计书籍 | 数据库教程书籍 | 平面与多媒体书籍 | 网络通讯书籍 | 系统管理书籍 | 网络安全书籍 | 认证考试书籍
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > C/C++教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ C/C++教程 ]的信息



本月文章推荐
.Windows Sockets:从套接字类派生.
.解析C++中的内部连接与外部连接.
.大教堂和市集.
.在Listboxes中加背景图.
.C/C++指针学习的两个经典实例.
.WinForm中的ListBox组件编程(1).
.树的生成与遍历.
.Turbo C使用释疑两则.
.C++箴言:绝不重定义继承的非虚拟.
.Turbo C下的寄存器变量.
.《c语言程序设计》第一章: C语言.
.C语言入门之函数(5).
.数据库设计指南(1).
.C++辨析系列谈.
.c++学习计划.
.2004年计算机等级考试二级C语言试.
.在 Linux 下建立软体套件.
.C++中获取WinNT/Win2k当前用户名.
.伪随机数生成及在VC++中的实现.
.nsd启动.

链表的C语言实现之循环链表及双向链表

发表日期:2008-3-8 |


一、循环链表

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

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

  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);
} 更多文章 更多内容请看C/C++进阶技术文档专题,或

  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);
}

上一篇:在C语言中如何处理时间和日期 人气:424
下一篇:C语言的常用库函数使用方法分析及用途 人气:887
浏览全部C/C++的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.3 Build 0
2008-7-6 飞天论坛FTBBS ASP v6.8 Build 0
2008-7-6 讯息内容管理系统 v2.1
2008-7-6 三五电影程序 v2.0
2008-7-6 神鹰腾讯小说小偷 v3.0
2008-7-6 EasyIDE Framework v1.0 Build 2
2008-7-6 品告CMS系统(电影版) v0.9
2008-7-6 QQ自动登录器 C# 源码 v1.0
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 GoodCalculator2.0版固件计算器
2008-7-5 RepoName源地址搜索工具 v1.21b
2008-7-5 AgileMessenger即时通讯工具 v1.
2008-7-5 TouchCopy多媒体管理软件 v3.13完
2008-7-5 VideosTone视频铃声 v1.1汉化破解
2008-7-5 TouchPad触摸板 v4.44破解版
2008-7-5 VideosTone破解补丁 v1.0
2008-7-5 Feeds GoogleReader客户端 v0.4.3


  发表评论
姓 名: 验证码:
内 容:
[ 汉字翻译拼音 ] [ 广告代码 ] [ 符号对照表 ] [ 进制转换 ] [ 经典小工具 ] [ 个税计算 ] [ 汉字简繁转换 ] [ 普通单位换算 ] [ 公制单位换算 ]
[ 生辰老黄历 ] [ 国内电话区号 ] [ 国家代码与域名缩写 ] [ 文字加密解密 ] [ 健康查询 ] [ 万年历 ] [ 手机号码查询 ] [ ip搜索 ] [ Google PR查询 ]
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報