链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述
关于数据结构等的学习,以及学习算法的感想感悟,听了郝斌老师的数据结构课程,其中他也提到了学习数据结构的或者算法的一些个人见解,我觉的很好,对我的帮助也是很大,算法本就是令人头疼的问题,因为自己并没有学习过算法的系统性的课程,现在还是处于不断摸索的阶段,好多算法题目根本就没有什么思路,导致自己对好多题目都很是头疼,就算是自己做过的一些算法的题目,再次遇到也还是不一定会做出来,他给出的建议就是,看懂别人的程序,然后自己去敲,一定会出错,然后调试,有错误接着调试,一直到没有错误为止,并且要时常的去复习自己敲过的代码,这个过程注定是枯燥的,但却是不得不经过的一个过程,一言难尽啊~,最后送自己三个字:注孤生.....
下面附上代码:
- /*链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示*/
- # include <stdio.h>
- # include <malloc.h>
- # include <stdlib.h>
- typedef struct Node
- {
- int data;//数据域
- struct Node * pNext;//指针域
- }NODE, *PNODE;//NODE等价于struct Node
- //函数声明
- PNODE create_list(void);
- void traverse_list(PNODE pHead);
- bool is_empty(PNODE pHead);
- int length_list(PNODE);
- bool insert_list(PNODE, int, int);//要插入一个数据的话,要知道这个链表,再一个是位置,再一个是要删除的元素
- bool delete_list(PNODE, int, int *);//要删除一个数据,要知道这个链表,再一个是位置,之所以定义了int * 型是因为要完成一个暂时的
- //存储,就像是实现回收站的功能一样
- void sort_list(PNODE);
- int main(void)
- {
- int val;
- PNODE pHead = NULL;//等价于 struct Node * pHead = NULL;把首节点的地址赋值给pHead(在一个链表中首节点和尾节点后面都是NULL,没有其他元素)
- //PNODE 等价于struct Node *
- pHead = create_list();
- traverse_list(pHead);
- printf("--------------------------------------\n");
- if (is_empty(pHead))
- printf("链表为空!\n");
- else
- printf("链表不空!\n");
- printf("--------------------------------------\n");
- int len = length_list(pHead);
- printf("链表的长度是%d\n", len);
- printf("--------------------------------------\n");
- printf("重新排序之后:");
- sort_list(pHead);
- traverse_list(pHead);
- printf("--------------------------------------\n");
- printf("插入新的节点后为:");
- insert_list(pHead,,);
- traverse_list(pHead);
- printf("--------------------------------------\n");
- , &val))
- {
- printf("删除成功,您删除的元素是:%d\n", val);
- }
- else
- {
- printf("删除失败!您删除的元素不存在!\n");
- }
- traverse_list(pHead);
- getchar();
- getchar();
- ;
- }
- //创建地址类型的地址,因为create_list 这个函数是要返回的地址
- //功能就是把头节点的地址返回,最终才能头节点才能指向一个链表
- PNODE create_list(void)
- {
- int len;//存放有效节点的个数
- int i;
- int val;//用来临时存放用户熟入的节点是值
- //前面说过只要是找到头节点,对于链表的操作就方便了,所以在这里我们首先先定义头节点
- PNODE pHead = (PNODE)malloc(sizeof(NODE));//定义头节点(不存放有效数据)
- if (NULL == pHead) //如果指针指向为空,则动态内存分配失败
- {
- printf("分配失败,程序终止!\n");
- exit(-);
- }
- PNODE pTail = pHead; //pHead 是指向头节点的,如果用户是输入节点的个数是0,那么只有一个“头节点”
- pTail->data = NULL; //此时把pHead 赋值给pTail,则就合理l,然后指针域为空(和初始化差不多...)
- printf("请您输入要生成链表节点的个数:len = ");
- scanf("%d", &len);
- ; i < len; i++)
- {
- printf();
- scanf("%d", &val);
- PNODE pNew = (PNODE)malloc(sizeof(NODE));//创建新节点,使之指针都指向每一个节点(循环了len次)
- if (NULL == pNew) //如果指针指向为空,则动态内存分配失败
- {
- printf("分配失败,程序终止!\n");
- exit(-);
- }
- /*
- pNew->data = val;//一个临时的节点
- pHead->pNext = pNew;//把pNew挂到pHead上
- pNew->pNext=NULL; //这个临时的节点最末尾是空
- */
- //上面/**/注释掉的这行代码是有问题的,上面注释掉的代码的含义是分别把头节点后面的节点都挂在头节点上,
- //导致头节点后面的节点的指针域丢失,而我们想的是只是把第一个节点挂在头节点上,后面的依次进行,即把第二个
- //节点挂在第一个节点的指针域上,依次类推,很明显上面所注释掉的代码是实现不了这个功能的
- //下面是改进之后的
- pNew->data = val; //把有效数据存入pNEW
- pTail->pNext = pNew; //把pNew 挂在pTail的后面(也就是pTail指针域指向,依次串起来)
- pNew->pNext = NULL;//把pNew的指针域清空
- pTail = pNew; //在把pNew赋值给pTai,这样就能循环,实现依次连接(而我们想的是只是把第一个节点挂在头节点上,后面的依次进行,即把第二个
- //节点挂在第一个节点的指针域上)
- }
- return pHead;
- }
- //遍历函数并不需要返回值,参数还是要有的,要不然怎么知道是对哪个对象进行的遍历!
- //还是定义指针变量 PNODE pHead 因为 traverse_list(pHead) 调用的是地址
- /*
- 链表的遍历写法的整体思路:
- 1. 定义一个指针变量p指向第一个有效的节点
- 2.判断这个节点的指针域是不是为空(如果不是就不是最后一个)
- 3.不为空就输出此节点的有效数据,并且p-pNext来指向下一个节点(不能用p++哦!)
- 4.如果为空的话,说明到来尾节点
- */
- void traverse_list(PNODE pHead)//怎样遍历,是不能像以前一样用数组的,以为数组是连续的,这里不连续
- {
- PNODE p = pHead->pNext;
- while (NULL != p)
- {
- printf("%d ", p->data);
- p = p->pNext;
- }
- printf("\n");
- }
- /*
- 说明:_Bool依然仍是整数类型,但与一般整型不同的是,_Bool变量只能赋值为0或1,非0的值都会被存储为1。
- C99还提供了一个头文件 <stdbool.h> 定义了bool代表_Bool,true代表1,false代表0。只要导入 stdbool.h ,
- 就能非常方便的操作布尔类型了。
- */
- //判断链表是否为空的函数
- bool is_empty(PNODE pHead)
- {
- if (NULL == pHead->pNext)
- return true;
- else
- return false;
- }
- //链表长度计算函数
- int length_list(PNODE pHead)
- {
- PNODE p = pHead->pNext;
- ;
- while (NULL != p)
- {
- ++len;
- p = p->pNext;//链表不为空的时候,p就往下移一个
- }
- return len;
- }
- //排序函数
- void sort_list(PNODE pHead)
- {
- int i, j, t, len = length_list(pHead);
- PNODE p, q;
- , p = pHead->pNext; i<len - ; ++i, p = p->pNext)
- {
- , q = p->pNext; j<len; ++j, q = q->pNext)
- {
- if (p->data > q->data)// 类似于数组中的:a[i] >a[j]
- {
- t = p->data; //类似于数组中的:t = a[i];
- p->data = q->data; //类似于数组中的:a[i] = a[j];
- q->data = t; //类似于数组中的:a[j] = t;
- }
- }
- }
- return;
- }
- //插入函数
- //在pHead 所指向链表的第pos个节点的前面插入一个新的结点,该节点的值是val,并且pos的值是从1开始的
- bool insert_list(PNODE pHead, int pos, int val)
- {
- ;
- PNODE p = pHead;
- )
- {
- p = p->pNext;
- ++i;
- }
- || NULL == p)
- return false;
- PNODE pNew = (PNODE)malloc(sizeof(NODE));//在插入之前先分配一个动态内存空间
- if (NULL == pNew)
- {
- printf("动态内存分配失败!\n");
- exit(-);
- }
- pNew->data = val;
- PNODE q = p->pNext;//具体见93行附近注释
- p->pNext = pNew;
- pNew->pNext = q;
- return true;
- }
- //节点删除函数
- bool delete_list(PNODE pHead, int pos, int * pVal)
- {
- ;
- PNODE p = pHead;
- )
- {
- p = p->pNext;
- ++i;
- }
- || NULL == p->pNext)
- return false;
- PNODE q = p->pNext;
- *pVal = q->data; //删除之前先保存
- //删除p节点后面的节点
- p->pNext = p->pNext->pNext;
- free(q);
- q = NULL;
- return true;
- }
- /*对于排序函数的一个说明,其实是用了一个广义的算法上的一个应用吧算是
- 算法:
- 狭义的算法是与数据的存储方式密切相关
- 广义的算法是与数据的存储方式无关
- 泛型:
- 利用某种技术达到的 效果就是:不同的存数方式,执行的操作是一样的
- */
链表插入和删除,判断链表是否为空,求链表长度算法的,链表排序算法演示——C语言描述的更多相关文章
- 28_链表插入和删除算法的演示.swf
#include<stdio.h> #include<malloc.h> #include <stdio.h> #include <stdlib.h> ...
- 数据结构Java实现03----单向链表的插入和删除
文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构: (物理存储结构上不连续,逻辑上连续:大小不固定) 概念: 链式存储结构是基于指针实现的.我们把一个数据 ...
- 面试之路(10)-BAT面试之java实现单链表的插入和删除
链表的结构: 链表在空间是不连续的,包括: 数据域(用于存储数据) 指针域(用于存储下一个node的指针) 单项链表的代码实现: 节点类 构造函数 数据域的get,set方法 指针域的get,set方 ...
- 数据结构Java实现02----单向链表的插入和删除
文本主要内容: 链表结构 单链表代码实现 单链表的效率分析 一.链表结构: (物理存储结构上不连续,逻辑上连续:大小不固定) 概念: 链式存储结构是基于指针实现的.我们把一个数据 ...
- 《数据结构与算法分析——C语言描述》ADT实现(NO.00) : 链表(Linked-List)
开始学习数据结构,使用的教材是机械工业出版社的<数据结构与算法分析——C语言描述>,计划将书中的ADT用C语言实现一遍,记录于此.下面是第一个最简单的结构——链表. 链表(Linked-L ...
- js算法初窥01(排序算法01-冒泡、选择、插入)
排序,我想大家一定经历过或者正在经历着.或许你不懂算法,对排序算法一无所知,但是你一定用过一些第三方库的api来一键排序,那么,在你享受便捷的同时,你是否想过它的底层是如何实现的?这样的算法实现方式是 ...
- (C语言版)链表(四)——实现双向循环链表创建、插入、删除、释放内存等简单操作
双向循环链表是基于双向链表的基础上实现的,和双向链表的操作差不多,唯一的区别就是它是个循环的链表,通过每个节点的两个指针把它们扣在一起组成一个环状.所以呢,每个节点都有前驱节点和后继节点(包括头节点和 ...
- 【线性表基础】顺序表和单链表的插入、删除等基本操作【Java版】
本文表述了线性表及其基本操作的代码[Java实现] 参考书籍 :<数据结构 --Java语言描述>/刘小晶 ,杜选主编 线性表需要的基本功能有:动态地增长或收缩:对线性表的任何数据元素进行 ...
- C语言习题 链表建立,插入,删除,输出
Problem B: C语言习题 链表建立,插入,删除,输出 Time Limit: 1 Sec Memory Limit: 128 MB Submit: 222 Solved: 92 [Subm ...
随机推荐
- Spring+SpringMVC+Mybaties整合之配置文件如何配置及内容解释--可直接拷贝使用--不定时更改之2017/4/27
以下配置可直接使用,只需更改包名. 关于内部标签的解释及用法,都以注解形式在代码内部说明.个人原创,转载需注明出处. 1,web.xml.添加jar包后首先需要配置WEB-INF下的web.xml文件 ...
- HttpClient研究学习总结
Http协议非常的重要,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人 ...
- bzoj2884 albus就是要第一个出场
Description 已知一个长度为n的正整数序列A(下标从1开始), 令 S = { x | 1 <= x <= n }, S 的幂集2^S定义为S 所有子集构成的集合.定义映射 f ...
- get和post提交数据的区别
get是客户端向服务器索取数据的请求,设定的初衷是,客户端(浏览器)给服务器发送请求,然后服务器再返回给客户端其要求的数据. 那么为什么说get也能提交数据呢? 我们仔细理解第一句话“客户端(浏览器) ...
- jquery的ajax与spring mvc对接注意事项
昨天一直纠结这么一个问题,应用场景是这样的: 这里登陆是通过jquery的ajax传输数据到后台controller类相应的映射mapping接收.本来是想,在后台验证成功之后返回一个视图modelA ...
- Python标准模块—Regular Expressions
作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 正则表达式是一门小语言,你可以在Python中或者其 ...
- springmvc 方法参数自定义的解析
1.实现HandlerMethodArgumentResolver接口: 2.在配置文件中添加配置<mvc:argument-resolvers> <bean class=&qu ...
- Thinkphp模板简单入门
Thinkphp模板概述: ThinkPHP内置了一个基于XML的性能卓越的模板引擎,这是一个专门为ThinkPHP服务的内置模板引擎,使用了XML标签库技术的编译型模板引擎,支持两种类型的模板标签, ...
- c#枚举值增加特性说明
c#枚举值增加特性说明 通过特性给一个枚举类型每个值增加一个字符串说明,用于打印或显示. 自定义打印特性 [AttributeUsage(AttributeTargets.Field)] public ...
- sublime Text2 快捷键精华版
Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+V:粘贴 ...