复习下C 链表操作(双向链表)
双向链表 创建、删除、反转、插入
//struct
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /**********************双向链表************************************/ typedef struct Student_Double
{
char name[];
int point;
struct Student_Double *preStu;
struct Student_Double *nextStu;
} StudentDouble; //创建双向链表
StudentDouble *CreateDoubleLinkTable(void){
int i = ;
StudentDouble *head = NULL;
head = (StudentDouble *)malloc(sizeof(StudentDouble));
head->name[]='\0';
head->point = ;
head->preStu = NULL;
head->nextStu = NULL; StudentDouble *temp,*currentNode;
currentNode=head;
while (i<=) {
temp = (StudentDouble *)malloc(sizeof(StudentDouble));
strncpy(temp->name,"Node",sizeof(temp->name));
temp->point = i;
temp->preStu = currentNode;
temp->nextStu = NULL; currentNode->nextStu = temp; currentNode = temp;
i++;
} return head;
}
//正序查询
StudentDouble * SelectDoubleLinkTableFormHead(StudentDouble *head){
StudentDouble *endNode = NULL;
StudentDouble *next = head->nextStu;
if (next == NULL) {
printf("查询失败,不是链式结构\n");
exit();
} int i =;
while (next) {
printf("index %d; studentName is %s; point is %d\n",i+,next->name,next->point);
if (next->nextStu == NULL) {
endNode = next;
printf("双向链表尾节点:%d \n",endNode->point);
}
next=next->nextStu;
i++;
}
return endNode;
}
//反序查询
void SelectDoubleLinkTableFormEnd(StudentDouble *end){ StudentDouble *pre = end->preStu;
if (pre==NULL) {
printf("查询失败,不是链式结构\n");
exit();
}
pre = end;
int i = ;
while (pre) {
if (pre->name[]=='\0') {
//头链
break;
}
printf("index %d; studentName is %s; point is %d\n",i+,pre->name,pre->point);
pre = pre->preStu;
i++;
}
} //双向链表 插入节点 上一节点序号|插入节点名
StudentDouble *insertStudentDoubleLinkTable(StudentDouble *head,char *content){
if (!content) {
exit();
}
//分割字符串
char *token;
char nodeName[];
int nodeIndex;
token = strtok(content,"|");
int i = ;
while (token != NULL) {
if (i>) {
strncpy(nodeName,token,sizeof(char[]));
}else{
nodeIndex = atoi(token);
}
token = strtok(NULL,"|");
i++;
} //查找节点
StudentDouble *next = head->nextStu;
if (next==NULL) {
printf("不是链式结构");
exit();
}
int search = ;
StudentDouble *searchNode = NULL;
while (next) {
if (next->point == nodeIndex) {
search = ;
searchNode = next;
}
next = next->nextStu;
}
if (search==) {
printf("没有找到节点序号为%d 的节点",nodeIndex);
exit();
}
//插入节点
StudentDouble *nextLinkTable = searchNode->nextStu;
//创建新节点
StudentDouble *new = (StudentDouble *)malloc(sizeof(StudentDouble));
strncpy(new->name,nodeName,sizeof(new->name));
new->point = ;//这两随机去的数。
new->preStu = searchNode;
new->nextStu = nextLinkTable; searchNode->nextStu = new; return head;
} //双向链表 删除节点
StudentDouble *DelegateDoubleLinkTable(StudentDouble *head,int nodeIndex){
//查找节点
StudentDouble *next = head->nextStu;
if (next==NULL) {
printf("不是链式结构");
exit();
}
int search = ;
StudentDouble *searchNode = NULL;
while (next) {
if (next->point == nodeIndex) {
search = ;
searchNode = next;
}
next = next->nextStu;
}
if (search==) {
printf("没有找到节点序号为%d 的节点",nodeIndex);
exit();
} StudentDouble *preNode = searchNode->preStu;
StudentDouble *nextNode = searchNode->nextStu; preNode->nextStu = nextNode;
nextNode->preStu = preNode; //释放
free(searchNode);
return head;
} int main(void){
char sf[];
int num;
/**
* 创建双向循环链表
*/
StudentDouble *head = NULL;
StudentDouble *end = NULL;
printf("开始创建双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
head = CreateDoubleLinkTable();
}
printf("正序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
end = SelectDoubleLinkTableFormHead(head);
} printf("反序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
printf("双向链表尾节点:%d \n",end->point);
if (end->point == ) {
printf("双向链表反向查询\n");
SelectDoubleLinkTableFormEnd(end);
}
} printf("插入双向链表 如:4(上一个节点序号)|name(要插入的节点名)\n");
scanf("%s",sf);
head = insertStudentDoubleLinkTable(head,sf);
SelectDoubleLinkTableFormHead(head); printf("删除双向链表节点 输入要删除节点序号\n");
scanf("%d",&num);
head = DelegateDoubleLinkTable(head,num);
SelectDoubleLinkTableFormHead(head); return ;
}
双向链表反转: 和前面 单向链表反转 同样思路。
遍历链表 , 游标指针为当前遍历到的节点currentNode。 后续节点 nextNode。新链表 newLinkTable 初始为NULL;
思路如下:
//反转 双向链表
StudentDouble * ReversionDoubleLinkTable(StudentDouble *head){
StudentDouble *next = head->nextStu;
if (next==NULL) {
printf("不是链式结构");
exit();
} StudentDouble *currentNode,*nextNode,*newLinkTable;
currentNode = next;
newLinkTable = NULL;
while (currentNode) { //保持后续节点
nextNode = currentNode->nextStu;
//断开
currentNode->nextStu = newLinkTable;
currentNode->preStu = NULL;
if (newLinkTable !=NULL) {
newLinkTable->preStu = currentNode;
}
//保存游标节点
newLinkTable = currentNode;
//重置游标节点
currentNode = nextNode;
} StudentDouble *newHead = (StudentDouble*)malloc(sizeof(StudentDouble));
newHead->name[]='\0';
newHead->point = ;
newHead->nextStu = newLinkTable;
newHead->preStu = NULL;
newLinkTable->preStu = newHead; return newHead;
}
int main(void){
char sf[];
int num;
/**
* 创建双向循环链表
*/
StudentDouble *head = NULL;
StudentDouble *end = NULL;
printf("开始创建双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
head = CreateDoubleLinkTable();
}
printf("正序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
end = SelectDoubleLinkTableFormHead(head);
} printf("反序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
printf("双向链表尾节点:%d \n",end->point);
if (end->point == ) {
printf("双向链表反向查询\n");
SelectDoubleLinkTableFormEnd(end);
}
} printf("反转双向链表 Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
head = ReversionDoubleLinkTable(head); printf("正序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
end = SelectDoubleLinkTableFormHead(head);
} printf("反序查询双向链表Y|N \n");
scanf("%s",sf);
if (strcmp(sf,"Y")==) {
printf("双向链表尾节点:%d \n",end->point);
if (end->point == ) {
printf("双向链表反向查询\n");
SelectDoubleLinkTableFormEnd(end);
}
}
} return ;
}
复习下C 链表操作(双向链表)的更多相关文章
- 复习下C 链表操作(单向链表)
Object-C 作为C 的包装语言(运行时.消息机制).如果不熟悉C 的话实在玩得太肤浅. 随便深入oc 内部都会接触到C. runtime .GCD.Block.消息机制... 所有强大的功能无不 ...
- 复习下C 链表操作(双向循环链表,查找循环节点)
双向循环链表 和 单向循环链表 查找循环节点 思路都是一样. 快慢指针查找法. 理论可参考 c 链表之 快慢指针 查找循环节点 typedef struct Student_Double { ]; ...
- 复习下C 链表操作(单向循环链表、查找循环节点)
循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表. 接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...
- linux 内核的链表操作(好文不得不转)
以下全部来自于http://www.ibm.com/developerworks/cn/linux/kernel/l-chain/index.html 无任何个人意见. 本文详细分析了 2.6.x 内 ...
- js数据结构之链表(单链表、双向链表、循环链表)
首先,链表有以下特点: 1. 存储空间不固定,可灵活扩充 2.方便多次的插入和删除,效率较高 单链表 单链表是最常用的链表,其对数据的操作均为单项的,向后查找的. /* 链表(基于对象) 此处为单链表 ...
- 【 C# 】(一) ------------- 泛型带头节点的单链表,双向链表实现
在编程领域,数据结构与算法向来都是提升编程能力的重点.而一般常见的数据结构是链表,栈,队列,树等.事实上C#也已经封装好了这些数据结构,在头文件 System.Collections.Generic ...
- SWUSTOJ 960A题总结,又完成一个讨厌的题,内含链表操作启发
今天debug了一个nice代码,先码在这里,SWUST OJ960 双向链表的操作问题 1000(ms) 10000(kb) 2994 / 8244 建立一个长度为n的带头结点的双向链表,使得该链表 ...
- C# 链表操作
关于链表操作,在C#当中微软已经提供了一个LinkedList<T>的数据结构,通过这个类提供的一系列方法就能够实现链表操作. 这里我提供一段代码,这是在论坛里面有人提问时给出的代码,它实 ...
- 线性链表的双向链表——java实现
.线性表链式存储结构:将采用一组地址的任意的存储单元存放线性表中的数据元素. 链表又可分为: 单链表:每个节点只保留一个引用,该引用指向当前节点的下一个节点,没有引用指向头结点,尾节点的next引用为 ...
随机推荐
- itextpdf 备忘
加删除线: .setUnderline(Color.BLACK, 2.0f, 0.0f, 6.0f, 0.0f, 1) https://developers.itextpdf.com/examples ...
- Android File Transfer
about a question in developing.. When you run app and created a file of db,but Android File Transfer ...
- 【DB2】SQL优化
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAA
- python之模块py_compile用法(将py文件转换为pyc文件)
# -*- coding: cp936 -*- #python 27 #xiaodeng #python之模块py_compile用法(将py文件转换为pyc文件):二进制文件,是由py文件经过编译后 ...
- shell笔记-算术运算
算术运算在Bash shell环境中,可以利用let.(( ))和[]执行基本的算术操作.而在进行高级操作时,expr和bc这两个工具也会非常有用.let命令可以直接执行基本的算术操作.当使用let时 ...
- linux 上配置tomcat、mysql 开机启动
1.tomcat 开机启动 方法一.修改系统文件 (已经尝试,可以) 1.修改/etc/rc.d/rc.local vi /etc/rc.d/rc.local 2.添加下面两行脚本,记住是两行,仅仅第 ...
- shell 脚本启动tomcat服务
#!/bin/bash # kill tomcat进程 tomcat_fashion_dev_pid=`ps aux|grep tomcat_fashion_dev|grep -v "gre ...
- JSP弹出对话框方式小结
转自:http://blog.csdn.net/ithomer/article/details/8033002 该博主(创业)另一博客地址: http://blog.mimvp.com JSP 网页在 ...
- LUA可变长参数 ... 三个点
本文翻译自 LUA官方文档 When a function is called, the list of arguments is adjusted to the length of the list ...
- GCD 容易让人迷惑的几个问题
写在开头: 本文旨在阐述一些大家容易产生迷惑的GCD相关内容,如果是需要了解一些GCD概念或者基础用法,可以看看这两篇文章:GCD 扫盲篇.巧谈GCD . 目录: 迷惑一:队列和线程的关系 迷惑二:G ...