/****************************************************/ 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语言实现的更多相关文章

  1. c语言实现--不带头结点的单链表操作

    1,不带头结点的单链表操作中,除了InitList(),GetElem(),ListInsert(),ListDelete()操作与带头结点的单链表有差别外,其它的操作基本上一样. 2,不带头结点单链 ...

  2. java编写带头结点的单链表

    最近在牛客网上练习在线编程,希望自己坚持下去,每天都坚持下去练习,给自己一个沉淀,不多说了 我遇到了一个用java实现单链表的题目,就自己在做题中将单链表完善了一下,希望大家作为参考也熟悉一下,自己 ...

  3. C/C++中创建(带头结点、不带头结点的)单链表

    1.带头结点的单链表(推荐使用带头结点的单链表)(采用尾插法) 了解单链表中节点的构成 从上图可知,节点包含数据域和指针域,因此,在对节点进行定义时,我们可以如下简单形式地定义: /* 定义链表 */ ...

  4. 链表习题(2)-一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点。

    /*一个集合用带头结点的单链表L表示,编写算法删除其值最大的结点.*/ /* 算法思想:使用pre,p,premax,max四个指针,pre和p进行比较,premax和max进行最后的删除操作 通过遍 ...

  5. 链表习题(1)-设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点

    /*设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点*/ /* 算法思想:设f(L,x)的功能是删除以L为首结点指针的单链表中所有值等于x的结点, 则显然有f(L->next,x)的 ...

  6. 有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成。

    有一个线性表,采用带头结点的单链表L来存储,设计一个算法将其逆置,且不能建立新节点,只能通过表中已有的节点的重新组合来完成. 分析:线性表中关于逆序的问题,就是用建立链表的头插法.而本题要求不能建立新 ...

  7. 不带头结点的单链表(基于c语言)

    本篇文章的代码大多使用无头结点的单链表: 相关定义: #include <stdio.h> #include <stdlib.h> #include <assert.h& ...

  8. 带头节点的单链表-------C语言实现

    /***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...

  9. Python实现不带头结点的单链表

    1 # 创建一个节点类 2 class Node: 3 def __init__(self, item): 4 self.item = item 5 self.next = None 6 7 8 # ...

随机推荐

  1. SQL中循环的实现方式

    一.第一种方法,游标 定义游标 DECLARE cur_ClubHeadCash CURSOR FAST_FORWARD READ_ONLY FOR,循环每行 FETCH NEXT FROM cur_ ...

  2. [CSP-S模拟测试58]题解

    以后题解还是单独放吧. A.Divisors 根号筛求所有数的因子,扫一遍去重统计即可. #include<cstdio> #include<iostream> #includ ...

  3. C# Winform版批量压缩图片程序

    需求 上周,领导给我分配了一个需求:服务器上的图片文件非常大,每天要用掉两个G的大小的空间,要做一个自动压缩图片的工具处理这些大图片.领导的思路是这样的: 1)打开一个图片,看它的属性里面象素是多少, ...

  4. 修改 DbVisualizer 自动完成快捷键

    1.找到 DbVisualizer 安装目录 lib目录 下的 dbvis.jar 包. 2.使用 WinRaR 打开dbvis.jar包,编辑 dbvis-actions.xml 文件(解压或直接修 ...

  5. 1、jQuery操作Dom

    1.添加元素 <code> <script language="JavaScript">$().ready(function(){$("input ...

  6. 一个线上Java空指针问题的排查经过

    某天,运营反馈,某商品下单异常 1.原来是一个空指针报错 根据用户输入的下单关键信息搜索日志系统看到如下报错 stackTrace: "java.lang.NullPointerExcept ...

  7. ABTest介绍及abtest流量切换实现

    本文为学习abtest切流方案方便以后查看大部分内容转载自原文 https://blog.csdn.net/tanweii163/article/details/80543083 互联网公司的业务发展 ...

  8. flask中配置并使用mongodb

    在你安装并运行了mongodb的情况下: 随便在一个文件中写入以下代码: import pymongo client = pymongo.MongoClient(host="localhos ...

  9. 38-python基础-python3-检查字典中是否存在键或值

    in 和 not in 操作符   请注意, 在前面的例子中,‘name’ in spam 本质上是一个简写版本.相当于'name' in spam.keys()

  10. iView的表单table

    // html<div class="exam-list"> <Table :columns="columns7" :data="d ...