链表操作函数 C

#include <stdlib.h>
#include <stdio.h>


typedef struct tagNode {
struct tagNode *fwd;
struct tagNode *bwd;
int value;
}DDL_S;


int valuePrint(DDL_S *rootp)
{
DDL_S *current;
DDL_S *next;
int i = 0;
printf("####\n");
//for(current = rootp->fwd; current->fwd != NULL; current = current->fwd){
// printf("%d", current->value);
//}
for(current = rootp; (next = current->fwd) != NULL; current = next){
printf("%c", next->value);
}
printf("\n");
return 0;
}


int interrupt(DDL_S *rootp)
{
DDL_S *current;
DDL_S *next;
DDL_S *tail;
DDL_S *current_1;


/*寻找尾节点*/
for(tail = rootp->fwd; tail->fwd != NULL; tail = tail->fwd){//$$$$方法1:tail指向首节点,循环遍历,跳出循环后tail指向尾节点
;
}
//for(current_1 = rootp; (tail = current_1->fwd) != NULL; current_1 = tail){
// ;
//}//$$$$方法2,current_1指向根节点,tail指向首节点,for循环跳出时,current_1指向尾节点,tail == NULL;


/*将链表ABCDEF打断重新排序为EFABCD*/
for(current = rootp; (next = current->fwd) != NULL; current = next ){
if(current->value == 'D'){
current->fwd = NULL;//D前指向NULL
tail->fwd = rootp->fwd;//F前指向A, $$$$方法1
//current_1->fwd = rootp->fwd;//F前指向A, $$$$方法2
rootp->fwd->bwd = tail;//A后指向F
//rootp->fwd->bwd = current_1;//A后指向F
next->bwd = NULL;//E后指向NULL
rootp->fwd = next;//根节点前指向E
rootp->bwd = current;//根节点后指向D
break;
}
}


return 0;
}


/*
**Description:对链表进行重组操作  
**将双向链表从给定的截断点分成两段,两段位置互换成为新链表。
**Input=NODE_S *breadPoint 截断点指针
**Return= NODE_S *res 新链表头结点指针
**Caution=入参合法性由调用者保证
**reGroup_1为方法1,reGroup_2为方法2,相比较而言,reGroup_2更好
*/
DDL_S *reGroup_1(DDL_S *breakPoint)
{
DDL_S *pre;
DDL_S *next;
DDL_S *current;
DDL_S *head;
DDL_S *tail;
DDL_S *rootp;
DDL_S *head_1;
DDL_S *tail_1;


rootp = (DDL_S *)malloc(sizeof(DDL_S));
if(rootp == NULL){
printf("malloc error\n");
}


/*寻找原首节点*/
for(current = breakPoint; (pre = current->bwd) != NULL; current = pre){
;
}//循环结束后,current指向原链表首节点
head = current;

/*寻找原尾节点*/
for(current = breakPoint; (next = current->fwd) != NULL; current = next){
;
}//循环结束后,current指向原链表尾节点
tail = current;


/*重排链表,为了好说明,那断点为E来举例,重排前后为ABCDEF -> EFABCD*/
(breakPoint->bwd)->fwd = NULL;//D前进指向NULL $$$$经验之谈,先排列断点处的两个节点
breakPoint->bwd = NULL;//E后退指向NULL
tail->fwd = head;//F前进指向A
head->bwd = tail;//A后退指向F
//(breakPoint->bwd)->fwd = NULL;//D前进指向NULL $$$$此时breakPoint->bwd == NULL, 所以(breakPoint->bwd)->fwd是非法的.所以重新排列时,要先排列断点处的两个节点,以降低出错的概率


/*打印重排后的链表*/
rootp->fwd = breakPoint;//????如果前面不给rootp分配内存,执行到这步会报错,不明白为什么
rootp->bwd = breakPoint->bwd;
valuePrint(rootp);


return breakPoint;
}




/*
**Description:对链表进行重组操作  
**将双向链表从给定的截断点分成两段,两段位置互换成为新链表。
**Input=NODE_S *breadPoint 截断点指针
**Return= NODE_S *res 新链表头结点指针
**Caution=入参合法性由调用者保证
*/
DDL_S *reGroup_2(DDL_S *breakPoint)
{
DDL_S *head;
DDL_S *tail;
DDL_S *rootp;


rootp = (DDL_S *)malloc(sizeof(DDL_S));
if(rootp == NULL){
printf("malloc error\n");
}
for(head = breakPoint; head->bwd != NULL; head = head->bwd){
;
}//循环结束后,head指向头节点


for(tail = breakPoint; tail->fwd != NULL; tail = tail->fwd){
;
}//循环结束后,tail指向尾节点


/*重排链表,为了好说明,那断点为E来举例,重排前后为ABCDEF -> EFABCD*/
(breakPoint->bwd)->fwd = NULL;//D前进指向NULL $$$$经验之谈,先排列断点处的两个节点
breakPoint->bwd = NULL;//E后退指向NULL
tail->fwd = head;//F前进指向A
head->bwd = tail;//A后退指向F
//(breakPoint->bwd)->fwd = NULL;//D前进指向NULL $$$$此时breakPoint->bwd == NULL, 所以(breakPoint->bwd)->fwd是非法的.所以重新排列时,要先排列断点处的两个节点,以降低出错的概率


/*打印重排后的链表*/
rootp->fwd = breakPoint;
rootp->bwd = breakPoint->bwd;
valuePrint(rootp);


return breakPoint;
}


int main()
{
/*双向链表初始化:申请内存,value分别赋值ABCDEF*/
DDL_S *Ap;
DDL_S *Bp;
DDL_S *Cp;
DDL_S *Dp;
DDL_S *Ep;
DDL_S *Fp;
DDL_S *rootp;


rootp = (DDL_S *)malloc(sizeof(DDL_S));
if(rootp == NULL){
printf("malloc error\n");
return -1;
}
Ap = (DDL_S *)malloc(sizeof(DDL_S));
if(Ap == NULL){
printf("malloc error\n");
return -1;
}
Bp = (DDL_S *)malloc(sizeof(DDL_S));
if(Bp == NULL){
printf("malloc error\n");
return -1;
}
Cp = (DDL_S *)malloc(sizeof(DDL_S));
if(Cp == NULL){
printf("malloc error\n");
return -1;
}
Dp = (DDL_S *)malloc(sizeof(DDL_S));
if(Dp == NULL){
printf("malloc error\n");
return -1;
}
Ep = (DDL_S *)malloc(sizeof(DDL_S));
if(Ep == NULL){
printf("malloc error\n");
return -1;
}
Fp = (DDL_S *)malloc(sizeof(DDL_S));
if(Fp == NULL){
printf("malloc error\n");
return -1;
}


rootp->fwd = Ap;
rootp->bwd = Fp;
rootp->value = 'a';

Ap->fwd = Bp;
Ap->bwd = NULL;
Ap->value = 'A';

Bp->fwd = Cp;
Bp->bwd = Ap;
Bp->value = 'B';

Cp->fwd = Dp;
Cp->bwd = Bp;
Cp->value = 'C';

Dp->fwd = Ep;
Dp->bwd = Cp;
Dp->value = 'D';

Ep->fwd = Fp;
Ep->bwd = Dp;
Ep->value = 'E';

Fp->fwd = NULL;
Fp->bwd = Ep;
Fp->value = 'F';




//valuePrint(rootp);//打印链表值
//interrupt(rootp);//打断链表,原链表首尾相接
//valuePrint(rootp);//打印新链表值
//reGroup_1(Cp);
reGroup_2(Bp);
//while(1);
return 0;
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值