/*双向链表*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*基础操作*/
//1.定义
typedef int data_t; //错误1 分号忘了加
typedef struct node_t{
data_t data;
struct node_t *prior, *next; //错误2是struct node_t,而不是node_t
}dlinklist;
//2.创建表,初始化表
dlinklist *create_dlinklist()
{
dlinklist *head = (dlinklist*)malloc(sizeof(dlinklist)); //malloc的用法不熟悉
if(NULL == head) return NULL;
head->data = -1;
head->next = head->prior = NULL;
return head;
}
//3.求表长
int get_len_dlinklist(dlinklist *head)
{
int len = 0;
if(NULL == head) return NULL;
dlinklist *p = head->next;//错误是head.next 空表是只有头结点的表,头结点不算长度
while(p != NULL) //错误是p!=NULL
{
len++;
p = p->next;
}
return len;
}
//4.判空
int dlinklist_is_empty(dlinklist *head)
{
if(NULL == head) return NULL;
return ((head->next == head->prior)?1:0);
}
//5.打印
void show_dlinklist(dlinklist *head)
{
if(NULL == head) return NULL;
dlinklist *p = head->next;
while(p != NULL)
{
printf("%d ",p->data);
p = p->next;
}
printf("\n");
}
//6.清空链表
void clear_dlinklist(dlinklist *head)
{
if(NULL == head) return NULL;
dlinklist *p = head->next;
dlinklist *q = NULL;
head->next = NULL;
while(p != NULL)
{
q = p->next;
free(p);
p = q; //p向后移一位
}
}
//7.销毁链表??
int destory_dlinklist(dlinklist** head)
{
free(*head);
head = NULL;
return 0;
}
/*增删改查*/
//1.头插法
int insert_head_dlinklist(dlinklist* head, data_t val)
{
if(NULL == head) return -1;
//准备new 节点
dlinklist *new = (dlinklist *)malloc(sizeof(dlinklist));
new->data = val; //
new->next = NULL;
new->prior = NULL;
//头插法 插入
if(head->next == NULL)
{
new->next = head->next;
new->prior = head;
head->next = new;
}else
{
new->next = head->next;
head->next->prior = new;
new->prior = head;
head->next = new;
}
return 0;
}
/*题目*/
//1.删除结点p
//找到结点p
dlinklist *get_node_dlinklist(dlinklist *head, int i)
{
dlinklist *p = head->next;
int j = 1;
while (p != head && j < i)
{
p = p->next;
j++;
}
while (p == head | j > i)
{
return -1;
}
return p;
}
int del_node_dlinklist(dlinklist *head, int i, data_t e)
{
dlinklist *p = NULL;
if(!(p = get_node_dlinklist(head,i))) return -1;
e = p->data;
p->prior->next = p->next;
p->next->prior = p->prior;
free(p);
return 0;
}
//2.在p结点之后插入一个节点
int insert_dlinklist(dlinklist *head, int i, data_t e)
{
dlinklist *p = NULL;
if(!(p = get_node_dlinklist(head,i))) return -1;
dlinklist *s = (dlinklist *)malloc(sizeof(dlinklist));
s->data=e;
s->next = p->next;
s->prior = p;
p->next->prior = s;
p->next =s;
}
//3.逆序双向表
dlinklist *reverse(dlinklist *head)
{
if(NULL == head || NULL == head->next) return head;
//指向首元结点
dlinklist *first = head->next;
//指向第二个节点
dlinklist *second = first->next;
//首元结点与后续节点断开
first->next = NULL;
dlinklist *third = NULL;
while(second)
{
third = second->next;
second->prior = NULL;
second->next = first;
first->prior = second;
//使下一节点成为当前节点
first = second;
//继续循环
second = third;
}
//将最后一个节点的前驱节点赋值为头结点指针
first->prior = head;
// 将头结点与后续节点连接
head->next = first;
return head;
}
//4.合并有序表?
dlinklist *merge(dlinklist *A, dlinklist *B)
{
dlinklist *r, *t, *p, *q;
r = A;
p = r->next;
r->next = NULL;
p->prior = NULL;//断开连接,单独取出A的首元素
t = B;
//先将A中p所指剩余结点插入新链表中
while (p != NULL)
{
//用q指向p的下一个结点
q = p->next;
//将p与新链表A中的结点比较有无相同值
while (r != NULL)
{
if (r->data == p->data)
{
//若相同则删除p所指结点,取链表中下一个值
free(p);
break;
}
r = r->next;
}
if (r == NULL)//若无相同值
{
//将p结点插入到新链表中
p->next = A->next;
p->prior = A;
if (A->next != NULL)
{
A->next->prior = p;
}
A->next = p;
}
p = q;
r = A;
}
//先将B中t所指剩余结点插入新链表中
r = A;
while (t != NULL)
{
//用q指向t的下一个结点
q = t->next;
//将t与新链表A中的结点比较有无相同值
while (r != NULL)
{
if (r->data == t->data)
{
//若相同则删除t所指结点,取链表中下一个值
free(t);
break;
}
r = r->next;
}
if (r == NULL)//若无相同值
{
//将p结点插入到新链表中
t->next = A->next;
t->prior = A;
if (A->next != NULL)
{
A->next->prior = t;
}
A->next = t;
}
t = q;
r = A;
}
return A;
}
//5.排序
dlinklist *sort_dlinklist(dlinklist *head) //函数返回值为头指针,形参也为头指针
{
int i=0,j=0;
int n= get_len_dlinklist(head); //调用统计节点个数的函数
dlinklist *p=head; //定义两个临时指针来进行数据处理
dlinklist *pn=head; //p和pn总是两个相邻的节点,且pn在p之后
//****冒泡排序****//
for(i=0;i<n;i++)
{
p=head->next;
pn=p->next;
for(j=0;j<n-1-i;j++)
{
if(p->data < pn->data) //判断,条件成立之后交换位置
{
if(pn->next==NULL) //判断是否为尾节点
{
//**交换位置代码**//
p->next=pn->next;
pn->prior=p->prior;
pn->next=p;
p->prior->next=pn;
p->prior=pn;
//**位置交换结束**//
}
else
{
//**交换位置代码**//
p->next=pn->next;
pn->prior=p->prior;
pn->next->prior=p;
p->prior->next=pn;
//下一行请注意//
pn->next=p;
p->prior=pn;
//**位置交换结束**//
pn=p->next; //位置交换结束之后进行指针偏移,pn指向p的下一个节点
}
}
else //条件不成立
{
p=p->next;
pn=p->next;
//如果未发生位置交换,则两个指针都要发生偏移
}
}
}
return head;
}
int main(int argc, char *argv[])
{
int a[6] = {1,3,5,7,9,11};
int b[6] = {2,4,6,8,10,12};
dlinklist* head1 = create_dlinklist();
for(int i = 0; i < 6; i++)
{
insert_head_dlinklist(head1,a[6-i-1]);
}
printf("list1:");
show_dlinklist(head1);
dlinklist* head2 = create_dlinklist();
for(int i = 0; i < 6; i++)
{
insert_head_dlinklist(head2,b[6-i-1]);
}
printf("list1:");
show_dlinklist(head2);
del_node_dlinklist(head1,2, 5); //删除的节点为第2位,从1开始数起
show_dlinklist(head1);
insert_dlinklist(head1, 4, 98);
show_dlinklist(head1);
reverse(head1);
show_dlinklist(head1);
sort_dlinklist(head1);
show_dlinklist(head1);
merge(head1, head2);
show_dlinklist(head1);
sort_dlinklist(head1);
show_dlinklist(head1);
return 0;
}
运行结果