#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Node {
int _id; char s[];
struct Node* pre;
struct Node* next;
};
void node_free(struct Node** q) {
if( *q != NULL) {
printf("free %d\n",(*q)->_id);
free(*q);
*q = NULL;
}
}
void node_print(struct Node* q) {
if (NULL == q) {
puts("节点打印:空节点,无可打印");
return;
}
printf("---id = %2d---", q->_id);
printf("preview = %10d ", q->pre);
printf("【address = %10d】 ", q);
printf("next = %10d\n", q->next);
}
void chain_print(struct Node* qFirst) {
if (qFirst == NULL) {
puts("没有元素可以打印");
return;
}
puts("----------↓↓↓打印链表------------");
// 遍历链表
struct Node* q;
for(q = qFirst; q != NULL; q=q->next ) {
node_print(q);
}
puts("----------↑↑↑打印链表------------");
} /*
* 为链表追加节点(加在最后)
* 参数:头节点,需要追加的节点
* 返回值:无
*/
void chain_add(struct Node* qFirst, struct Node* qAdd) {
// 定位到链表头
struct Node* q = qFirst;
// 只要后面(next)有节点,往后找;直到没有next的节点(最后一个)
for(q; q->next != NULL; q=q->next ) {
node_print(q);
}
// 此时定位在最后一个节点,下图1
// 将新节点加在最后节点的后面(next)
q->next = qAdd;// 下图2
qAdd->pre = q;//下图3
} /*
* 删除节点
* 参数:1.头结点 2.待删除的结点
* 因为被删除的结点需要置空,所以需要使用二级指针
* 返回值:-1 删除失败/0 删除成功
*/
int chain_remove(struct Node** qFirst, struct Node** qRemove) {
struct Node* qPre = NULL;
struct Node* qNext = NULL;
struct Node* q = *qFirst; // 1.输入Check
if(NULL == *qRemove){
puts("删无可删!");
return -;
}else{
printf("删除节点:id=%d\n", (*qRemove)->_id);
} // 2.删除头结点,特殊对待
if(*qFirst == *qRemove ) { if((*qFirst)->next == NULL){
// 就一个头结点的场合
node_free(qFirst);
}else{
qNext = q->next;
node_free(qFirst);
*qFirst = qNext;
} return ;
}
// 遍历链表
for(q; q != NULL; q=q->next ) {
if (q == *qRemove) {
qPre = q->pre;
qNext = q->next; if (qNext!=NULL) {
qNext->pre = qPre;
qPre->next= qNext;
} else {
// 尾节点的场合
qPre->next= NULL;
}
node_free(qRemove);
return ;
}
} }
void chain_clear(struct Node** qFirst) {
puts("\n----------Clear------------"); if (qFirst == NULL) {
puts("已经是空");
return;
} // 遍历链表
// 不断删除第一个元素
while(*qFirst != NULL) {
chain_remove(qFirst,qFirst);
}
}
struct Node* chain_get(struct Node* qFirst, int index) {
printf("---获取index = %d的节点:", index);
int i = ;
// 遍历链表
struct Node* q = qFirst;
for(q; q!= NULL; q=q->next,i++ ) {
if (index == i) {
return q;
}
}
return NULL;
}
/*
* 获取链表长度(即 节点的个数)
* 参数: 头节点
* 返回值:链表长度
*/
int chain_count(struct Node* qFirst) {
if (qFirst == NULL) {
// 头节点都没有,长度为0
return ;
}
int i = ;
// 遍历链表
struct Node* q = qFirst;
for(q; q != NULL; q=q->next) {
// 顺藤摸瓜,直到最后一个节点
i++;// 找到一个就+1
}
return i;
}
struct Node* node_new(int id) {
struct Node* q = (struct Node*)malloc(sizeof(struct Node));
memset(q, , sizeof(struct Node));
q->_id = id;
return q;
}
void testFunction(){
struct Node* q1 = node_new();
struct Node* q2 = node_new();
struct Node* q3 = node_new();
struct Node* q4 = node_new();
struct Node* q5 = node_new();
puts("###有节点的链表:");
printf("count = %d\n",chain_count(NULL));
chain_print(NULL); puts("\n###1个节点的链表:");
printf("count = %d\n",chain_count(q1));
chain_print(q1); // 增
chain_add(q1, q2);
chain_add(q1, q3);
chain_add(q1, q4);
chain_add(q1, q5); puts("\n###5个节点的链表:");
printf("count = %d\n",chain_count(q1));
chain_print(q1); puts("");
struct Node* pGet;
pGet = chain_get(q1, );
node_print(pGet);
pGet = chain_get(q1, );
node_print(pGet);
pGet = chain_get(q1, );
node_print(pGet);
pGet = chain_get(q1, );
node_print(pGet); // 删
puts("\n###删除测试");
chain_remove(&q1,&q5);
chain_print(q1);
chain_remove(&q1,&q3);
chain_print(q1);
chain_remove(&q1,&q1);
chain_print(q1);
//chain_remove(&q1,&q1);
//chain_print(q1);
//chain_remove(&q1,&q1);
//chain_print(q1);
//chain_remove(&q1,&q1);
//chain_print(q1); chain_clear(&q1);
chain_print(q1); getchar();
}
int _tmain(int argc, _TCHAR* argv[]){
testFunction();
return ;
}

C语言,链表操作的更多相关文章

  1. C语言链表操作模板(添加,删除,遍历,排序)

    C语言链表操作模板,摘自郝斌的C语言视频教程,简单的修改成了纯C格式.当年照着视频学习的时候记录下来的,在使用的时候直接拿来修改修改修改能节约不少时间的. /********************* ...

  2. ZT C语言链表操作(新增单向链表的逆序建立)

    这个不好懂,不如看 转贴:C语言链表基本操作http://www.cnblogs.com/jeanschen/p/3542668.html ZT 链表逆序http://www.cnblogs.com/ ...

  3. C 语言链表操作例程 (待完善)

    #include<stdio.h>#include<malloc.h>#include<conio.h>#include<stdlib.h>#inclu ...

  4. C语言,单链表操作(增删改查)(version 0.1)

    这天要面试,提前把链表操作重新写了一遍.备份一下,以备不时之需. 希望有人能看到这篇代码,并指正. // File Name : list.h #include "stdafx.h" ...

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

    可能是顺序表研究的细致了一点,单链表操作一下子就实现了.这里先实现带头结点的单链表操作. 大概有以下知识点. 1;结点:结点就是单链表中研究的数据元素,结点中存储数据的部分称为数据域,存储直接后继地址 ...

  6. C语言 链表

    原文:C语言 链表 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将要实现19个功能. ...

  7. C语言链表实例--玩转链表

    下图为最一简单链表的示意图: 第 0 个结点称为头结点,它存放有第一个结点的首地址,它没有数据,只是一个指针变量.以下的每个结点都分为两个域,一个是数据域,存放各种实际的数据,如学号 num,姓名 n ...

  8. JAVA 链表操作:循环链表

    主要分析示例: 一.循环链表简述 二.单链表循环链表 三.双链表循环链表 一.循环链表简述 循环链表即链表形成了一个循环的结构,尾节点不再指向NULL,而是指向头节点HEAD,此时判定链表的结束是尾节 ...

  9. go语言文件操作,这期资料比较详细( 欢迎加入go语言群: 218160862 )

    go语言文件操作,这期资料比较详细 欢迎加入go语言群: go语言深圳群 golang深圳 218160862 点击加入 文件操作 func Open(name string) (file *File ...

  10. C语言字符串操作总结大全(超详细)

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作  strcpy(p, p1) 复制字符串  strncpy(p, p1, n) 复制指定长度字符串  strcat( ...

随机推荐

  1. DPDK - gsg文档(介绍与编译)

    && Hugepage 提前分配hugepage内存,可以减少虚拟页地址转换到物理地址所需的时间. 相关命令: 在虚拟机上运行时,在没有NUMA的机器上,执行“echo 1024 &g ...

  2. JavaScript语言里判断一个整数,属于哪个范围:大于0;小于0;等于0

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. vue 配合vue-resource调用接口,获取数据

    1.先用node+express+mysql简单配置一下后台 const express = require('express');const mysql = require('mysql');con ...

  4. ConcurrentDictionary对象

    ConcurrentDictionary<int, List<a>> dic = new ConcurrentDictionary<int, List<a>& ...

  5. 命令行编译多个java文件

    如何使用命令行编译多个java文件 文件结构: method 1 cd javaproject javac -sourcepath javapath -d classpath javapath/*.j ...

  6. 2017第八届蓝桥杯C/C++语言A组

    一:题目: 标题:迷宫 X星球的一处迷宫游乐场建在某个小山坡上.它是由10x10相互连通的小房间组成的. 房间的地板上写着一个很大的字母.我们假设玩家是面朝上坡的方向站立,则:L表示走到左边的房间,R ...

  7. NodeJS 学习笔记

    1. NodeJs的事件模型被称为非阻塞式IO或者事件驱动IO 2. Node.js 几乎每一个 API 都是支持回调函数的. 3. Node.js 基本上所有的事件机制都是用设计模式中观察者模式实现 ...

  8. windows进程查看

    查看目前使用的端口 netstat -nao 查看目前运行程序的具体路径 命令行输入wmic接着输入process

  9. 部署activiti 5.15.1的Activiti Explorer

    1.从官网下载activiti包,将其中的activiti-explorer.war文件拷贝到tomcat的webapps目录下: 2.将mysql驱动包文件mysql-connector-java- ...

  10. linux后台执行命令:&与nohup的用法

    & 这种方法很简单,就是在命令之后加个“&”符号就可以了,如下: ./test & 这样一来,test程序就在后台运行了.但是,这样处理还不够,因为这样做虽然程序是在后台运行了 ...