不带头结点的单链表------C语言实现
/****************************************************/ File name:no_head_link.c
Author:SimonKly Version:0.1 Date: 2017.5.20
Description:不带头节点的单链表
Funcion List:
*****************************************************/ #include <stdio.h>
#include <stdlib.h> typedef struct node
{
int id;
struct node * next;
}* Link, Node; /*创建链表*/
void create_link(Link * head)
{
*head = NULL;//空链表
} /*头插*/
void insert_node_head(Link * head, Link new_node)
{
new_node->next = *head;
*head = new_node;
} #if 1
/*尾插*/
void insert_node_tail(Link * head, Link new_node)
{
Link p = NULL; if (*head == NULL)
{
*head =new_node;
new_node->next = NULL;
return ;
}
else
{
p = *head;
while (p->next != NULL)
{
p = p->next;
}
p->next = new_node;
new_node->next = NULL;
}
}
#endif /*输出链表*/
void display_link(Link head)
{
Link p = NULL; p = head; if(p == NULL)
{
printf("link is empty!\n");
return ;
} while (p != NULL)
{
printf("id = %d\n", p->id);
p = p->next;
} putchar();
} /*检查malloc是否分配成功*/
void is_malloc_ok(Link new_node)
{
if (new_node == NULL)
{
printf("malloc error!\n");
exit(-);
}
} /*创建节点*/
void create_node(Link * new_node)
{
*new_node = (Link)malloc(sizeof(Node)); is_malloc_ok(*new_node);
} /*释放节点*/
void realse_node(Link * head)
{
Link p = NULL; p = *head;
while (*head != NULL)
{
*head = (*head)->next;//head移动
free(p);//释放head之前的节点
p = *head;
}
} /*中间插入节点*/
void insert_node_mid(Link * head, Link new_node, int loc)
{
int i;
Link p = NULL; p = *head; for(i = ; i < loc; i++)
{
p = p->next;
} new_node->next = p->next;
p->next = new_node;
} /*中间插入,前面*/
void insert_node_mid_front(Link * head, Link new_node)
{
Link p = NULL, q = NULL; p = q = *head; if (*head == NULL)
{
printf("link is empty\n");
return ;
} while (p != NULL && p->id != new_node->id)
{
q = p;
p = p->next;
} if (p == NULL)
{
printf("No such node in link!\n");
free(new_node);
return ;
}
if (p->id == (*head)->id)
{
new_node->next = *head;
*head = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
#if 1
/*删除节点*/
void delete_node(Link * head, int data)
{
Link p = NULL, q = NULL; q = p = *head; if (p == NULL)//链表为空的时候
{
printf("link is empty!\n");
return ;
}
else//链表不为空的时候
{
while (p != NULL && p->id != data)//寻找节点
{
q = p;
p = p->next;
} if ((*head)->id == data)//删除节点为头节点时
{
*head = (*head)->next;
free(p);//free(q);
}
else//删除节点不为头节点,尾节点不用考虑
{
q->next = p->next;
free(p);
}
}
}
#endif #if 0
void delete_node(Link * head, int data)
{
Link p = NULL, q = NULL; q = p = *head; if (p == NULL)//链表为空的时候
{
printf("link is empty!\n");
return ;
}
else//链表不为空的时候
{
while (p != NULL && (p->next)->id != data)//寻找节点
{
p = p->next;
} if ((*head)->id == data)//删除节点为头节点时
{
*head = (*head)->next;
free(p);//free(q);
}
else//删除节点不为头节点,尾节点不用考虑
{
q = p->next;
p->next = q->next;
free(q);
}
}
}
#endif /*插入之后依旧有序*/
void insert_node_seq(Link * head, Link new_node)
{
Link p = NULL, q = NULL; p = q = *head; if (p == NULL)//链表为空的时候
{
*head = new_node;
new_node->next = NULL;
}
else
{
while (p != NULL && p->id < new_node->id)//寻找位置
{
q = p;
p = p->next;
} if ((*head)->id > new_node->id)//找到的节点为头节点
{
new_node->next = *head;
*head = new_node;
}
else
{
q->next = new_node;
new_node->next = p;
}
}
} #if 1
/*插入依旧有序实现方法二*/
void insert_node_seq_1(Link * head, Link new_node)
{
Link p = NULL;
Link q = NULL; p = q = *head; if (p == NULL)//空链表
{
*head = new_node;
new_node->next =NULL;
}
else
{
while ((p->id < new_node->id) && (p->next != NULL))
{
q = p;
p = p->next;
} if ((*head)->next == NULL)//一个节点的时候
{
if (p->id > new_node->id)
{
new_node->next = *head;
*head = new_node;
}
else
{
p->next = new_node;
}
}
else
{
if (p->next == NULL)//尾节点
{
if (p->id > new_node->id)//插入前
{
q->next = new_node;
new_node->next = p;
}
else
{
p->next = new_node;
}
}
else//不是尾节点
{
if((*head)->id > new_node->id)//头节点
{
new_node->next = *head;
*head = new_node;
}
else//中间插入时
{
q->next = new_node;
new_node->next = p;
}
}
}/*end of if()*/
}/*end of if (p == NULL)*/
}
#endif int main()
{
Link head = NULL;//防止出现野指针
Link new_node = NULL;//防止出现野指针
int i;
int data; create_link(&head);//创建链表 for (i = ; i < ; i++)//值域赋值,并插入新节点
{
// new_node = (Link)malloc(sizeof(Node));//创建新节点
create_node(&new_node);
// new_node->id = i + 1;//赋值
// insert_node_head(&head, new_node);//插入节点,头插
// insert_node_tail(&head, new_node);//插入节点,尾插 printf("please input node value:\n");
scanf("%d", &new_node->id);
insert_node_seq(&head, new_node);
// insert_node_seq_1(&head, new_node);
display_link(head);//输出节点的值域
} display_link(head);//输出节点的值域 #if 0
create_node(&new_node);
new_node->id = i + ;
insert_node_mid(&head, new_node, );//指定位置插入,中间插入
putchar();
display_link(head);//输出节点的值域 #if 0
create_node(&new_node);
scanf("%d", &new_node->id);
insert_node_mid_front(&head, new_node);
display_link(head);//输出节点的值域
#endif scanf("%d", &i);
delete_node(&head, i);//删除指定节点
display_link(head); #if 0 create_node(&new_node);
scanf("%d", &new_node->id);
insert_node_seq(&head, new_node);//有序插入指定元素
display_link(head);
#endif
#endif
realse_node(&head);//释放节点 display_link(head);//输出节点的值域
return ;
}
由于链式数据结构中有指针的各种指向问题,所以在纸上画图是比较容易理解。
其中在对头指针(注意是头指针,不是头节点,两个不是一个概念,头指针是整个链表的操作的基础,链表存在的象征,头指针是整个“链表公司”的一把手,头头结点是链表中的第一个元素)的操作,除了在插入,删除和销毁中头指针的指向发生改变,需要直接对头指针head操作外,其他方法都不要对头指针进行操作,以免丢失整个链表。
在对链表中的增加时,需要考虑链表中开始存在的元老级的“人物”,所以我们不能随便就对它们变换“岗位”,我得先找到”接班人“之后再对这些元老级的岗位进行调整。
在对链表中的节点进行删除时,也需要首先考虑这些元老级的“人物”,毕竟人家没有功劳也有苦劳,我们得代理好它走后它的”上级“和他的”下级“沟通交流的问题。
代码中的一些条件编译和注释是未完成一些功能的另一种方法。
在销毁整个链表时,相当于整个链表公司破产,作为公司一把手的head,依次需要对手下任劳任怨的员工进行思想工作。当整个公司没有员工时,一把手也什么都没有了即NULL。
代码中的功能函数包括:
1.创建链表
2.创建节点
3.插入节点------------头插,尾插以及插入即有序,指定位置插入的方法,根据需要选择合适的方法
头插:实现链式栈
尾插:实现链式队列
4.删除节点
5.销毁整个链
6.判断malloc函数是否执行成功
7.输出链
不带头结点的单链表------C语言实现的更多相关文章
- c语言实现--不带头结点的单链表操作
1,不带头结点的单链表操作中,除了InitList(),GetElem(),ListInsert(),ListDelete()操作与带头结点的单链表有差别外,其它的操作基本上一样. 2,不带头结点单链 ...
- java编写带头结点的单链表
最近在牛客网上练习在线编程,希望自己坚持下去,每天都坚持下去练习,给自己一个沉淀,不多说了 我遇到了一个用java实现单链表的题目,就自己在做题中将单链表完善了一下,希望大家作为参考也熟悉一下,自己 ...
- C/C++中创建(带头结点、不带头结点的)单链表
1.带头结点的单链表(推荐使用带头结点的单链表)(采用尾插法) 了解单链表中节点的构成 从上图可知,节点包含数据域和指针域,因此,在对节点进行定义时,我们可以如下简单形式地定义: /* 定义链表 */ ...
- 链表习题(2)-一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点。
/*一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点.*/ /* 算法思想:使用pre,p,premax,max四个指针,pre和p进行比较,premax和max进行最后的删除操作 通过遍 ...
- 链表习题(1)-设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
/*设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点*/ /* 算法思想:设f(L,x)的功能是删除以L为首结点指针的单链表中所有值等于x的结点, 则显然有f(L->next,x)的 ...
- 有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成。
有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成. 分析:线性表中关于逆序的问题,就是用建立链表的头插法.而本题要求不能建立新 ...
- 不带头结点的单链表(基于c语言)
本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...
- 带头节点的单链表-------C语言实现
/***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...
- Python实现不带头结点的单链表
1 # 创建一个节点类 2 class Node: 3 def __init__(self, item): 4 self.item = item 5 self.next = None 6 7 8 # ...
随机推荐
- Selenium之Android使用学习
20140507 Selenium一般用在web自动化上,为什么Android上也能用呢? 如图,手机端和DB联动:手机端的客户端给server发数据流,进行增删改查操作,这种写数据用update更新 ...
- percona-toolkit工具包的安装和初步使用
percona-toolkit工具包的安装和初步使用 原文地址:http://blog.csdn.net/yumushui/article/details/42919601 一.percona-too ...
- Effective Objective-C 2.0
Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法 作者:Matt Galloway(英) 译者:爱飞翔 出版社:机械工业出版社 出版年:2014-01 ...
- 《ArcGIS Runtime SDK for .NET开发笔记》--三维功能
介绍 在ArcGIS Runtim SDK for .NET 10.2.6中,新添加了三维地图功能.在ArcGIS中,我们将三维地图称为Scene(场景),所以在Runtime SDK SDK for ...
- 【计算机网络mooc】二、物理层
1.物理层基本概念 物理层只考虑传输bit流,不包括网线等传输媒体(可认为是第0层),屏蔽传输媒体的差异,不同的传输媒体定义不同标准. 主要任务:确定与传输媒体的接口的特性. 机械特性:网线上面的水晶 ...
- 用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单
目录 目录 前文列表 实现 post 视图函数 在 posthtml 中添加表单 效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写个轻博客 (2) - Hell ...
- 20140914 1到N自然数排序
1.关于一道1到N自然数排序的华为面试题 http://blog.csdn.net/hongyuan19/article/details/1887656 为什么想进入华为 你对华为了解多少? 华为给我 ...
- 16-vim-查找字符或单词-01-查找
1.常规查找 查找到指定内容之后,使用n查找下一个出现的位置. 命令 功能 /str 查找str 例:/python n 查找下一个 N 查找上一个 2.单词快速匹配(常用) 命令 功能 * 向下查找 ...
- css中的居中问题
前两天写了一篇关于display:table的用法,里面涉及到居中的问题,这两天愈发觉得css中的居中是一个值得关注的问题,现总结如下. 一.垂直居中 (1)inline或者inline-*元素 1. ...
- Maven入门指南11:使用Nexus搭建Maven私服
1 . 私服简介 私服是架设在局域网的一种特殊的远程仓库,目的是代理远程仓库及部署第三方构件.有了私服之后,当 Maven 需要下载构件时,直接请求私服,私服上存在则下载到本地仓库:否则,私服请求外部 ...