#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define bzero(a, b) memset(a, 0, b)//windows平台下无bzero函数。 增加宏拓展移植性
struct node
{
int data; //有效数据
struct node *pLast;//指向上一个节点的指针
struct node *pNext;//指向下一个节点的指针
};
struct node * make_node(int data)
{
struct node *p=(struct node*)malloc(sizeof(struct node));
if(NULL==p)
{
printf("malloc error
");
return NULL;
}
//清理申请到的内存
bzero(p,sizeof(struct node));
//填充节点
p->data=data;
p->pLast=NULL;
p->pNext=NULL;//将来要指向下一个节点的首地址
//实际操作时将下一个节点的malloc 返回的指针给他。
return p;
}
void ergodic(struct node *pH)//遍历
{
int cnt=0;
struct node *p=pH;
/* printf("------开始遍历------
");//这样包含头结点
while(NULL!=p->pNext)
{
printf("第%d节点数据为为%d
",cnt,p->data);
p=p->pNext;
cnt++;
}
printf("第%d节点数据为为%d
",cnt,p->data);
printf("------结束遍历------
");
} */
printf("------开始遍历------
");
while(NULL!=p->pNext)
{
cnt++;
p=p->pNext;
printf("第%d节点数据为为%d
",cnt,p->data);
}
printf("------结束遍历------
");
}
void reverse_ergodic(struct node *pT)//反向遍历
{
int cnt=0;
struct node *p=pT;
printf("------开始遍历------
");
while(NULL!=p->pLast)
{
cnt++;
printf("第%d节点数据为为%d
",cnt,p->data);
p=p->pLast;
}
printf("------结束遍历------
");
}
void in_tail(struct node *pH,struct node *p_new)
{ //先找到尾节点
//插入
int cnt=0;
struct node *p=pH;
while(NULL!=p->pNext)
{
p=p->pNext;
cnt++;
}
p->pNext=p_new; //插到之前最后的节点后面(后向指针)
p_new->pLast=p; //之前最后的节点后面防盗新节点的向前的指针(前向指针)
pH->data=cnt+1;// 头节点数据代表链表个数
//前指针的pLast与新指针的pNext无变动
}
void in_head(struct node *pH,struct node *p_new)
{ //1。将原1好节点地址给新节点后向指针
//2。将头指针指向新节点
//3。原1号节点前向指针指向新节点
//4。新节点前向指针指向头结点
int cnt=0;
struct node *p=pH;
while(NULL!=p->pNext)
{
p=p->pNext;
cnt++;
}
if(NULL==pH->pNext)
{
pH->pNext=p_new;
p_new->pLast=pH;
}else
{
p_new->pNext=pH->pNext;
pH->pNext=p_new;
p_new->pNext->pLast=p_new; //不判断的话p_new->pNext->pLast会引发段错误
p_new->pLast=pH;
}
pH->data=cnt+1;// 头节点数据代表链表个数
//前指针的pLast与新指针的pNext无变动
}
void del_1(struct node *pH,int num)//根据节点数删除 不能删除0(头节点)
{
//1找到
//2删除
//删除(释放内存。指向下一个)
int cnt=0;
struct node *p=pH;
struct node *p_sb;;//临时变量释放内存用
while(NULL!=p->pNext)
{
cnt++;
if(num==cnt)
{
p_sb=p->pNext;//p为预删除点的上一个节点
p->pNext=p->pNext->pNext;//跳过欲删除节点指向下下个节点(删除正向节点)
if(NULL==p->pNext)
{
//说明P为现在最后一个节点
}
else
{
p->pNext->pLast=p;//(删除反向节点)
}
free(p_sb);//释放内存
break;
}
p=p->pNext;//不满足上述条件时 寻找下一个节点
}
}
void del_2(struct node *pH,int data)//删除指定数据
{
//1找到
//2删除
//删除(释放内存。指向下一个)
struct node *p=pH;
struct node *p_sb;;//临时变量释放内存用
while(NULL!=p->pNext)
{
if(data==p->pNext->data)//p为预删除点的上一个节点
{ p_sb=p->pNext;
p->pNext=p->pNext->pNext;//跳过欲删除节点指向下下个节点(删除正向节点)
if(NULL==p->pNext)
{
//说明P为现在最后一个节点
}
else
{
p->pNext->pLast=p;//(删除反向节点)
}
free(p_sb);
continue;
}
p=p->pNext;
}
}
int main()
{
struct node *pHead=make_node(0);//初始化头节点;
in_head(pHead,make_node(1));
in_head(pHead,make_node(1));
in_head(pHead,make_node(3));
in_head(pHead,make_node(4));
reverse_ergodic(pHead->pNext->pNext->pNext->pNext);
ergodic(pHead);
ergodic(pHead);
del_2(pHead,1);
reverse_ergodic(pHead->pNext->pNext);
ergodic(pHead);
return 0;
}