单向循环链表的创建/插入/删除/输出算法
2014-07-16 11:45
381 查看
单向循环链表
2> 为了高效的实现某些功能,为单向循环链表设置一个尾指针较为合适(当然设置头指针也是可以的)。
注:第二点提到的高效体现在:访问尾结点直接用设置的尾指针即可;访问头结点,即就是设置的尾指针的后继结点。
#include <stdlib.h>
#define N 7
typedef struct node {
int data ;
struct node *next;
} SN;
SN * creatlink ( int a[] )
{
SN * tail = NULL, *p;
//tail是所设置的尾指针, p是程序中遍历整个链表的指针。
int i;
for ( i = 0; i < N; i++ ) {
p = ( SN * ) malloc ( sizeof ( SN ) );
p->data = a[i];
if ( !tail ) {
//当tail为NULL时,表示当前结点是所创建的第一个结点。
tail->next = tail = p;
}
else {
//直接将p结点插入在尾结点后成为新的尾结点即可。
p->next = tail->next;
tail = tail->next = p;
}
}
return tail;
}
/*在进行单向循环链表的输出时,利用do-while结构比较简单易懂,否则需要分情况使得程序出现相同代码*/
void printlink ( SN *tail )
{
SN * p = tail;
do {
printf ("%5d", p->next->data);
p = p->next;
} while ( p != tail );
}
int main ( void )
{
SN * tail;
int a
= { 10, 20, 30, 40, 50, 60, 70 };
//创建单向循环链表
tail = creatlink ( a );
//输出单向循环链表
printlink ( tail );
return 0;
}
SN * delnode ( SN * tail, int delval )
{
//单向链表的数据域无重复值
SN * p, * delp;
p = tail;
do {
if ( p->next->data == delval )
break;
else
p = p->next;
} while ( p != tail ); //循环结束
if ( p == tail && tail->next->data != delval ) { //没有找到待删结点
printf ("Not found!\n");
}
else { //找到待删结点
if ( tail->neat == tail ) {
//表明此时链表中仅有这一个结点且当前需要删除它。
free ( tail );
tail = NULL;
}
else {
//此时链表中有两个结点及其以上
delp = p->next;
p->next = delp->next;
if ( delp == tail ) {
//判断当前所要删除结点是不是尾结点,如果是则需要先挪尾指针,否则直接释放删除结点
tail = p;
}
free ( delp );
}
}
return tail;
}
{
//tail即尾指针, s即插入结点
//设单向循环链表非空且数据域的值升序有序,使得插入后,新链表依然升序有序
SN * p = tail;
do {
if ( p->next->data >= s->data ) {
break;
}
else
p = p->next;
} while ( p != tail );
if ( p == tail && tail->next->data < s->data ) {
//此时表明待插结点数据大于当前尾结点数据域值,所以插入结点将成为新的尾结点,即需挪尾指针
tail = s;
}
//接下来只需要进行插入即可
s->next = p->next;
p->next = s;
return tail;
}
附录:以上仅仅是本人在学习单向循环链中的学习与实践。由于将删除模块与插入模块分开写,所以main函数没有写出来,读者可以根据自己的理解,对main函数进行正确的添加修改。
特点:
1> 将单向链表的尾结点指针域放头结点地址,即尾结点就是头结点的前驱结点。2> 为了高效的实现某些功能,为单向循环链表设置一个尾指针较为合适(当然设置头指针也是可以的)。
注:第二点提到的高效体现在:访问尾结点直接用设置的尾指针即可;访问头结点,即就是设置的尾指针的后继结点。
实现单向链表的创建以及输出
#include <stdio.h>#include <stdlib.h>
#define N 7
typedef struct node {
int data ;
struct node *next;
} SN;
SN * creatlink ( int a[] )
{
SN * tail = NULL, *p;
//tail是所设置的尾指针, p是程序中遍历整个链表的指针。
int i;
for ( i = 0; i < N; i++ ) {
p = ( SN * ) malloc ( sizeof ( SN ) );
p->data = a[i];
if ( !tail ) {
//当tail为NULL时,表示当前结点是所创建的第一个结点。
tail->next = tail = p;
}
else {
//直接将p结点插入在尾结点后成为新的尾结点即可。
p->next = tail->next;
tail = tail->next = p;
}
}
return tail;
}
/*在进行单向循环链表的输出时,利用do-while结构比较简单易懂,否则需要分情况使得程序出现相同代码*/
void printlink ( SN *tail )
{
SN * p = tail;
do {
printf ("%5d", p->next->data);
p = p->next;
} while ( p != tail );
}
int main ( void )
{
SN * tail;
int a
= { 10, 20, 30, 40, 50, 60, 70 };
//创建单向循环链表
tail = creatlink ( a );
//输出单向循环链表
printlink ( tail );
return 0;
}
单向链表的删除算法
特点:单向循环链表在删除时,和以前的链表的删除算法一样,待删结点的前驱上一定要有一个指针,需要特别注意的是:尾结点的删除,因为专门设置了一个尾指针,所以在删除尾结点时,一定要记得挪尾指针。SN * delnode ( SN * tail, int delval )
{
//单向链表的数据域无重复值
SN * p, * delp;
p = tail;
do {
if ( p->next->data == delval )
break;
else
p = p->next;
} while ( p != tail ); //循环结束
if ( p == tail && tail->next->data != delval ) { //没有找到待删结点
printf ("Not found!\n");
}
else { //找到待删结点
if ( tail->neat == tail ) {
//表明此时链表中仅有这一个结点且当前需要删除它。
free ( tail );
tail = NULL;
}
else {
//此时链表中有两个结点及其以上
delp = p->next;
p->next = delp->next;
if ( delp == tail ) {
//判断当前所要删除结点是不是尾结点,如果是则需要先挪尾指针,否则直接释放删除结点
tail = p;
}
free ( delp );
}
}
return tail;
}
单向循环链表的插入算法
SN * insertnode ( SN * tail, SN * s ){
//tail即尾指针, s即插入结点
//设单向循环链表非空且数据域的值升序有序,使得插入后,新链表依然升序有序
SN * p = tail;
do {
if ( p->next->data >= s->data ) {
break;
}
else
p = p->next;
} while ( p != tail );
if ( p == tail && tail->next->data < s->data ) {
//此时表明待插结点数据大于当前尾结点数据域值,所以插入结点将成为新的尾结点,即需挪尾指针
tail = s;
}
//接下来只需要进行插入即可
s->next = p->next;
p->next = s;
return tail;
}
附录:以上仅仅是本人在学习单向循环链中的学习与实践。由于将删除模块与插入模块分开写,所以main函数没有写出来,读者可以根据自己的理解,对main函数进行正确的添加修改。
相关文章推荐
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- 单向循环链表(建表、插入、删除、输出)
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- 单向循环链表创建、遍历、插入、删除、查找(按位置,按元素值)、清空、销毁
- 循环链表 实现对循环链表的初始化,创建,插入,删除,输出操作
- 实现单向循环链表的创建、测长、打印、插入、删除及逆置
- 常见算法:C语言中链表的操作(创建,插入,删除,输出)
- 两种方法实现单向链表的创建、遍历、删除、查找、逆序输出(循环法和递归法)
- (C语言版)链表(二)——实现单向循环链表创建、插入、删除、释放内存等简单操作
- (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作
- 单向链表的创建 删除 插入
- 链表的创建,插入,删除,和输出
- list 链表的 创建、输出(打印)、删除、插入 2011.07.26
- 链表(创建,插入,删除和打印输出)
- 一道习题:链表的创建、输出、删除、插入
- 学习笔记——C语言实现单链表的基本操作:创建、输出、插入结点、删除结点、逆序链表
- 单链表的创建(头插尾插),表长,输出,插入,删除,查找,逆置,分解长两个链表(奇数偶数链表),查找倒数第k个元素,产出相同元素
- 编程菜鸟的日记-初学尝试编程-顺序表的类定义及其基本操作算法(创建表、元素插入、元素删除、顺序查找、测表空、求表长、输出等)
- 单向链表小练习--》创建链表头,添加删除链表节点,释放链表内存,选择插入数据
- 链表的创建、取长、输出、插入、删除、逆序