双向链表比单链表多了一个保存前一个结点位置的指针域prior,操作与单链表也差不多!
这里的运算借鉴了很多人,当时写得要奔溃啦!所以在学习过程中,不能一味的自己走,适当的借鉴还是有点用处的(开玩笑的,别死抄就行!)。
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int data_t;
typedef struct node{
data_t data; //数据域:保存数据
struct node *next; //指针域:保存下一个节点的地址
struct node *prior; //指针域:保存上一个节点的地址
}dlinklist;
//初始化
dlinklist *creatDlinklist(void)
{
dlinklist *head = (dlinklist *)malloc(sizeof(dlinklist));
if(head == NULL)
{
perror("malloc");
return NULL;
}
head->prior = NULL;
head->next = NULL; //头节点:辅助工具
head->data = -1;
return head;
}
//判空
int dlinklist_is_empty(dlinklist *head)
{
return (head->next == NULL)?1:0;
}
//求表长
int dlinklist_length(dlinklist *head)
{
int len = 0;
dlinklist *p = head->next; //p指向第一个有效节点
while(p != NULL)
{
len++;
p=p->next;
}
return len;
}
//按位置添加节点
int dlinklistInsertByPos(dlinklist *head, int pos, data_t data)
{
int len = dlinklist_length(head);
if(pos <0 || pos > len)
{
printf("pos 位置不合法\n");
return -1;
}
dlinklist *new = (dlinklist *)malloc(sizeof(dlinklist));
if(new == NULL)
{
perror("malloc dlinklist");
return -1;
}
new->data = data;
new->prior = NULL;
new->next = NULL;
//找到pos节点的前一个节点的位置
dlinklist *p = head;
while(pos--)
{
p=p->next;
}
//插入元素
if(p->next != NULL) //中间
{
new->next = p->next;
new->prior = p;
p->next = new;
new->next->prior = new;
}
else { //末尾
new->next = p->next;
p->next = new;
new->prior = p;
}
}
//按位置删除节点
int dlinklistDeleteByPos(dlinklist *head, int pos)
{
if(dlinklist_is_empty(head))
{
printf("dlinklist is empty\n");
return -1;
}
int len = dlinklist_length(head);
if(pos < 0 || pos >= len)
{
printf("pos 位置不合法\n");
return -1;
}
dlinklist *p = head;
while(pos--)
{
p=p->next;
}
dlinklist *q = p->next;
if(q->next != NULL) //中间
{
p->next = q->next;
q->next->prior = p;
free(q);
q=NULL;
}
else{ //末尾
p->next = NULL;
free(q);
q = NULL;
}
}
//按位置查找节点
data_t dlinklist_weicha(dlinklist *head,int pos)
{
if(dlinklist_is_empty(head))
{
printf("biao null\n");
return -1;
}
int len=dlinklist_length(head);
if(pos<0 || pos>len)
{
printf("pos不合法\n");
return -1;
}
dlinklist *p=head->next;
while(pos--)
{
p=p->next;
}
return p->data;
}
//按位置修改节点
int dlinklist_weixiu(dlinklist *head,int pos,data_t data)
{
if(dlinklist_is_empty(head))
{
printf("biao is null");
return -1;
}
int len=dlinklist_length(head);
if(pos<0 || pos>len)
{
printf("pos不合法\n");
return -1;
}
dlinklist *p=head->next;
while(pos--)
{
p=p->next;
}
p->data=data;
return 0;
}
//按值查找节点
int dlinklist_zhicha(dlinklist *head,data_t data)
{
if(dlinklist_is_empty(head))
{
printf("biao kong\n");
return -1;
}
dlinklist *p=head->next;
int i=0;
while(p!=NULL)
{
if(p->data==data)
{
return i;
}
i++;
p=p->next;
}
}
//按值删除节点
int dlinklist_zhishan(dlinklist *head,data_t data)
{
int a=dlinklist_zhicha(head,data);
dlinklistDeleteByPos(head,a);
return 0;
}
//按值修改节点
int dlinklist_zhixiu(dlinklist *head,data_t old,data_t new)
{
int a=dlinklist_zhicha(head,old);
dlinklist_weixiu(head,a,new);
return 0;
}
//清空链表
int dlinklist_clear(dlinklist *head)
{
if(dlinklist_is_empty(head))
{
printf("biao kong\n");
return -1;
}
dlinklist *p=head;
dlinklist *q=NULL;
while(p!=NULL)
{
q=p->next;
p->next=q->next;
free(q);
q=NULL;
}
}
//销毁链表
void dlinklist_xiaohui(dlinklist **head)
{
dlinklist_clear(*head);
free(head);
head=NULL;
}
//打印
void dlinklist_display(dlinklist *head)
{
dlinklist *p = head->next;
while(p!=NULL)
{
printf("%d ", p->data);
p=p->next;
}
puts("");
}
//逆序(头插法)
int dlinklist_nixu(dlinklist *head)
{
if(dlinklist_is_empty(head))
{
printf("biao is null\n");
return -1;
}
dlinklist *p=head;
dlinklist *q=p;
while(p->next!=NULL)
{
q= p->next;
if(q->next!=NULL)
{
p->next = q->next;
q->next->prior = p;
}
else
{
p->next=NULL;
}
head->prior = q;
q->next = head;
head = q;
}
dlinklist_display(head);
return 0;
}
int main(int argc, const char *argv[])
{
dlinklist *head = creatDlinklist();
if(head == NULL)
{
perror("creatDlinklist");
return -1;
}
//判断表空
int m = dlinklist_is_empty(head);
printf("m = %d\n", m);
//插入数据
int i = 0;
while(i<10)
{
dlinklistInsertByPos(head, i, i+1);
i++;
}
dlinklist_display(head);
//删除元素
dlinklistDeleteByPos(head, 5);
dlinklist_display(head);
//位查找,位修改
dlinklist_weicha(head,5);
dlinklist_weixiu(head,5,99);
dlinklist_display(head);
//值查找
int b=dlinklist_zhicha(head,99);
printf("%d\n",b);
//值修改
dlinklist_zhixiu(head,99,66);
dlinklist_display(head);
//值删除
dlinklist_zhishan(head,66);
dlinklist_display(head);
//逆序
dlinklist_nixu(head);
// dlinklist_display(head);
return 0;
}
这里的逆序有点问题,算法有待提高!
链表就得多练,加油兄弟们!