//
#include "stdafx.h"
///关键代码开始
/*
*程序功能:对双向链表操作,主要包括:插入结点、删除结点、查找结点等基本操作
*需要注意的是,链表中附加了一个结点root_p
*root_p是链表的根节点,root_p中的data字段存储的是当前链表中的总结点个数
*root_p->prev指向链表中第一个存放数据的结点,root_p->next指向链表中最后一个存放数据的结点;
*当链表为空时,root_p->prev和root_p->next都为NULL
*/
#include<stdio.h>
#include<stdlib.h>
struct node
{
struct node *prev; /*指向前一个结点的指针*/
int data;
struct node *next; /*指向后一个结点的指针*/
};
void srand(unsigned int seed);
extern int printf(const char *format,...);
int dll_insert(struct node *root_p, int value); /*插入结点,插入成功返回1,否则返回0*/
int dll_delete(struct node *root_p, int value); /*删除结点,插入成功返回1,否则返回0*/
int dll_member(struct node *root_p, int value); /*查找结点,如果存在返回1,否则返回0*/
void dll_print(struct node *root_p); /*打印链表*/
int dll_insert(struct node *root_p, int value)
{
struct node *save_p, *curr_p;
struct node *new_p;
save_p = NULL;
curr_p = root_p->prev;
while (curr_p != NULL && curr_p->data < value)
curr_p = curr_p->next;// 从小到大排序插入
if (curr_p != NULL && curr_p->data == value)
return 0;// 相等则返回,即不允许重复
if ((new_p = (struct node *)malloc(sizeof(struct node))) == NULL)
return 0;
new_p->data = value;
if (curr_p != NULL)
save_p = curr_p->prev;// 找到前驱
else if (root_p->data != 0)
save_p = root_p->next;// 找到前驱 , 前驱为最后一个元素!!! 走到此说明插入到末尾.
new_p->next = curr_p; // 新节点lianru
new_p->prev = save_p;
if (save_p == NULL)
root_p->prev = new_p;
else save_p->next = new_p;
if (curr_p == NULL) root_p->next = new_p;
else curr_p->prev = new_p;
root_p->data++;
return 1;
}
int dll_delete(struct node *root_p, int value)
{
struct node *save_p, *curr_p, *next_p;
curr_p = root_p->prev;
while (curr_p != NULL && curr_p->data<value)
curr_p = curr_p->next;
if (curr_p != NULL && curr_p->data == value)
{
save_p = curr_p->prev;
next_p = curr_p->next;
if (save_p != NULL) save_p->next = next_p;
else root_p->prev = next_p;
if (next_p != NULL) next_p->prev = save_p;
else root_p->next = save_p;
root_p->data--;
return 1;
}
else return 0; /* 空链表 或者 没有找到要删除的内容*/
}
int dll_member(struct node *root_p, int value)
{
struct node *curr_p = root_p->prev;
while (curr_p != NULL && curr_p->data<value)
curr_p = curr_p->next;
if (curr_p != NULL && curr_p->data == value) return 1;
else return 0;
}
void dll_print(struct node *root_p)
{
struct node *curr_p = root_p->prev;
printf("total number of nodes = %d .\n", root_p->data);
while (curr_p != NULL)
{
printf("%d ", curr_p->data);
curr_p = curr_p->next;
}
printf("\n");
}
///关键代码结束
int _tmain(int argc, _TCHAR* argv[])
{
struct node *root_p;
int i;
/*root_p是链表的根节点,但是它并不存储链表的有效结点,
root_p中的data存储的是当前链表中的总结点个数
root_p->prev指向链表中第一个存放数据的结点,
root_p->next指向链表中最后一个存放数据的结点
*/
root_p = (struct node *) malloc(sizeof(struct node));
root_p->prev = root_p->next = NULL;
root_p->data = 0;// 专门准备一个头节点
srand(5); //随机数
printf("insert...\n");
for (i = 0; i<3; i++)
dll_insert(root_p, rand() % 100);
dll_print(root_p);
printf("\nmember...\n");
printf("10?exist : %d\n", dll_member(root_p, 10));
printf("65?exist : %d\n", dll_member(root_p, 65));
printf("75?exist : %d\n", dll_member(root_p, 75));
printf("9?exist : %d\n", dll_member(root_p, 9));
printf("70?exist : %d\n", dll_member(root_p, 70));
printf("100?exist : %d\n", dll_member(root_p, 100));
printf("\ndelete\n");
dll_delete(root_p, 10);
dll_delete(root_p, 65);
dll_delete(root_p, 75);
dll_delete(root_p, 9);
dll_delete(root_p, 70);
dll_delete(root_p, 100);
dll_print(root_p);
return 0;