1、节点定义
typedef struct DListElement_
{
void * data;
struct DListElement_ *prev;
struct DListElement_ *next;
}DListElement;
- 1
- 2
- 3
- 4
- 5
- 6
2、链表定义
typedef struct DList_
{
int size;
DListElement *head;
DListElement *tail;
}Dlist;
- 1
- 2
- 3
- 4
- 5
- 6
3、从某个节点的头部插入
int dlist_ins_prev(Dlist *list, DListElement *element, const void *data)
{
DListElement *new_element;
if (element == NULL && list->size != 0)//给定的节点无效
return -1;
if ((new_element = (DListElement *)malloc(sizeof(DListElement))) == NULL)
return -1;
new_element->data = (void *)data;
if (list->size == 0)//插入的为头节点
{
list->head = new_element;
list->tail = new_element;
new_element->prev = NULL;
new_element->next = NULL;
}
else//剩下的情况插入操作都是一样的
{
element->prev->next = new_element;
new_element->prev = element->prev;
element->prev = new_element;
new_element->next = element;
}
list->size++;
return;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
4、从某个节点的尾部插入
int dlist_ins_next(Dlist *list, DListElement *element, const void *data)
{
DListElement *new_element;
if (element == NULL && list->size != 0)
return -1;
if ((new_element = (DListElement *)malloc(sizeof(DListElement))) == NULL)
return -1;
new_element->data = (void *)data;
if (list->size == 0)//插入的为头节点
{
list->head = new_element;
list->tail = new_element;
new_element->prev = NULL;
new_element->next = NULL;
}
else
{
if (element->next == NULL)//插入的为尾节点
{
new_element->next = NULL;
list->tail = new_element;
}
else
{
new_element->next = element->next;
element->next->prev = new_element;
}
element->next = new_element;
new_element->prev = element;
}
list->size++;
return;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
5、删除节点
int dlist_rm_node(Dlist *list, DListElement *element, void **data)
{
if (element == NULL || list->size == 0)
return -1;
//这里有一个关于二重指针作为传出参数的操作,主要原因是,因为我们需要传出的是一个一重指针的值,所以需要传入他的地址,即二重指针来获取。如果传入一重指针,则最后的结果和两个变量的问题一样。
*data = element->data;//获取节点的数据
if (element->prev == NULL)//删除头部节点
{
list->head = element->next;
list->head->prev = NULL;
}
if (element->next == NULL)//删除尾部节点
{
list->tail = element->prev;
list->tail->next = NULL;
}
else//删除中间节点
{
element->prev = element->next;
element->next->prev = element->prev;
}
if (element != NULL)
{
free(element);
}
list->size--;
return;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
6、链表的遍历
//遍历整个链表
int dlist_ergodic(Dlist *list)
{
DListElement *p;
p = list->head;
while (p->next != NULL)
{
printf("%d-", (int)(p->data));
p = p->next;
}
printf("%d-", (int)(p->data));
printf("\n链表的长度为%d.\n", list->size);
return;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
总结:
关于二重指针做传出参数这个问题,我个人认为是这样的,如果你想要获取一个变量的值,那可以传入一个一重指针;如果想要获取一个一重指针的值,那就要传入一个二重指针,总之要传进去的永远是他的地址才可以被修改。
到这里我又想到一个问题,关于交换X,Y两个数的值,和这个类似的处理方式。
void swp(int *x, int *y)
{
int t = 0;
t = *x;
*x = *y;
*y = t;
}
#define swp(x,y) {x = x+y; y = x-y; x = x-y;}