okok 双向链表 之后会给出循环链表的解析 本人自己写的 欢迎各位纠正
老规矩 我们先上主函数 来看看总体是个啥情况(
今天不知道为啥这个代码段段变成黑色的了)
先创建双链表 用initLine这个函数实现
输出函数 用printLine实现
插入 insertLine
删除 deleteLine
一般情况下 那俩函数插入和删除 应该是i,x 和y来代替 40,2和2
这样可以实现删除不同的位置节点操作(
int main(){
line *head=NULL;
printf("创建双链表操作\n");
head=initLine(head);
printLine(head);
//create line
printf("插入操作\n");
head=insertLine(head,40,2); //为了简化直接写参数了
printLine(head);
//insert Line
printf("删除操作\n");
head=deleteLine(head,2); //为了简化直接写参数了
printLine(head);
//delete Line
return 0;
}
我们先来看第二行的三个变量
number表示的是结点的个数
pos 表示的是 当前位置
input_data 代表的是输入的数据
我最难理解的是Line * list=head;
我想 head占的是内存里的一块地址 不能来回变换 需要通过指针来实现调用
line 就是我们定义的一个节点的结构体
line * head 就是一个指向line类型的指针变量 head
后面就是一些指针断开 重新确定指向方向的过程 比较容易理解 看代码就行
line* initLine(line * head){
int number,pos=1,input_data;
printf("请输入创建结点的大小\n");
scanf("%d",&number);
if(number<1){return NULL;} //输入非法直接结束
//头结点创建///
head=(line*)malloc(sizeof(line));
head->pre=NULL;
head->next=NULL;
printf("输入第%d个数据\n",pos++);
scanf("%d",&input_data);
head->data=input_data;
line * list=head;
while (pos<=number) {
line * body=(line*)malloc(sizeof(line));
body->pre=NULL;
body->next=NULL;
printf("输入第%d个数据\n",pos++);
scanf("%d",&input_data);
body->data=input_data;
list->next=body;
body->pre=list;
list=list->next;
}
return head;
下面的呢 是插入操作定义的函数
插入呢 由于有新的节点加入所以我们也要申请空间 (来给他住哈哈哈哈哈哈比较形象)
后面的删除操作函数就不用申请新节点
line * insertLine(line * head,int data,int add){
//三个参数分别为:进行此操作的双链表,插入的数据,插入的位置
//新建数据域为data的结点
line * temp=(line*)malloc(sizeof(line));
temp->data=data;
temp->pre=NULL;
temp->next=NULL;
//插入到链表头,要特殊考虑
if (add==1) {
temp->next=head;
head->pre=temp;
head=temp;
}else{
line * body=head;
//找到要插入位置的前一个结点
for (int i=1; i<add-1; i++) {
body=body->next;
}
//判断条件为真,说明插入位置为链表尾
if (body->next==NULL) {
body->next=temp;
temp->pre=body;
}else{
body->next->pre=temp;
temp->next=body->next;
body->next=temp;
temp->pre=body;
}
}
return head;
}
下面 删除函数 对对对 确实没有申请新空间了 但是好像多了点别的什么东西
free()是什么捏 释放空间啦 删除之后 那个节点所占用的空间 我们也用不到了 所以要释放这部分空间
//删除元素
line * deleteLine(line * head,int data){
//输入的参数分别为进行此操作的双链表,需要删除的数据
line * list=head;
//遍历链表
while (list) {
//判断是否与此元素相等
//删除该点方法为将该结点前一结点的next指向该节点后一结点
//同时将该结点的后一结点的pre指向该节点的前一结点
if (list->data==data) {
list->pre->next=list->next;
list->next->pre=list->pre;
free(list);
printf("--删除成功--\n");
return head;
}
list=list->next;
}
printf("Error:没有找到该元素,没有产生删除\n");
return head;
}
这段代码呢 好像没有修改节点数据的函数 不过比较简单 后期有时间会写的
不过 完全可以依葫芦画瓢 来自己尝试
下面 我的桌面在D盘 大家不要学我 把文件保存在桌面哦
okokokok 完整代码时刻
#include<stdio.h>
#include<stdlib.h>
typedef struct line{
int data; //data
struct line *pre; //pre node
struct line *next; //next node
}line;
//分别表示该结点的前驱(pre),后继(next),以及当前数据(data)
//遍历双链表,同时打印元素数据
void printLine(line *head){
line *list = head;
int pos=1;
while(list){
printf("第%d个数据是:%d\n",pos++,list->data);
list=list->next;
}
}
//创建双链表
line* initLine(line * head){
int number,pos=1,input_data;
printf("请输入创建结点的大小\n");
scanf("%d",&number);
if(number<1){return NULL;} //输入非法直接结束
//头结点创建///
head=(line*)malloc(sizeof(line));
head->pre=NULL;
head->next=NULL;
printf("输入第%d个数据\n",pos++);
scanf("%d",&input_data);
head->data=input_data;
line * list=head;
while (pos<=number) {
line * body=(line*)malloc(sizeof(line));
body->pre=NULL;
body->next=NULL;
printf("输入第%d个数据\n",pos++);
scanf("%d",&input_data);
body->data=input_data;
list->next=body;
body->pre=list;
list=list->next;
}
return head;
}
//插入数据
line * insertLine(line * head,int data,int add){
//三个参数分别为:进行此操作的双链表,插入的数据,插入的位置
//新建数据域为data的结点
line * temp=(line*)malloc(sizeof(line));
temp->data=data;
temp->pre=NULL;
temp->next=NULL;
//插入到链表头,要特殊考虑
if (add==1) {
temp->next=head;
head->pre=temp;
head=temp;
}else{
line * body=head;
//找到要插入位置的前一个结点
for (int i=1; i<add-1; i++) {
body=body->next;
}
//判断条件为真,说明插入位置为链表尾
if (body->next==NULL) {
body->next=temp;
temp->pre=body;
}else{
body->next->pre=temp;
temp->next=body->next;
body->next=temp;
temp->pre=body;
}
}
return head;
}
//删除元素
line * deleteLine(line * head,int data){
//输入的参数分别为进行此操作的双链表,需要删除的数据
line * list=head;
//遍历链表
while (list) {
//判断是否与此元素相等
//删除该点方法为将该结点前一结点的next指向该节点后一结点
//同时将该结点的后一结点的pre指向该节点的前一结点
if (list->data==data) {
list->pre->next=list->next;
list->next->pre=list->pre;
free(list);
printf("--删除成功--\n");
return head;
}
list=list->next;
}
printf("Error:没有找到该元素,没有产生删除\n");
return head;
}
int main(){
line *head=NULL;
printf("创建双链表操作\n");
head=initLine(head);
printLine(head);
//create line
printf("插入操作\n");
head=insertLine(head,40,2); //为了简化直接写参数了
printLine(head);
//insert Line
printf("删除操作\n");
head=deleteLine(head,2); //为了简化直接写参数了
printLine(head);
//delete Line
return 0;
}
选看: 由 上一个文章的单链表 我们可知 是将i作为位置 用for循环 一个个遍历找到的 链表嘛
不能像数组一样直接找到第i个
但是这个玩意是双链表啊 他比单链表有一点点的优化空间
就是它可以从两头中的任意一边来遍历寻找i 怎么确定是从哪边呢 那边近(短路径)就从哪边呗。
那么怎么让机器知道呢 判断 i和链表长度一半的大小 分俩种情况就就可以喽)