typedef int STATUS;
typedef int Element;
//定义结点
typedef struct Node {
Element data;
struct Node *pre;
struct Node *next;
}Node;
typedef struct Node * LinkList;
//遍历打印
STATUS show(LinkList L) {
//头结点是无效数据,所以取L->next
LinkList temp = L->next;
//容错判断
if (temp == NULL) {
printf("该链表为空");
return ERROR;
}
while (temp) {
printf("%d, ",temp->data);
temp = temp->next;
}
printf("\n");
return SUCCESS;
}
//1.创建双向链表
STATUS ListCreat(LinkList *L) {
//1.创建头结点: *L指向头结点
*L = (LinkList)malloc(sizeof(Node));
if (*L == NULL) {
return ERROR;
}
(*L)->next = NULL;
(*L)->pre = NULL;
(*L)->data = -999;/*无效值定义*/
//2.新增数据:for循环插入数据-尾插法
LinkList p = *L;/*新建p,方便赋值操作*/
for (int i = 0; i < 10; i ++) {
//1.创建临时结点
LinkList temp = (LinkList)malloc(sizeof(Node));
temp->data = i;
temp->pre = NULL;
temp->next = NULL;
//2.建立双向链表关系
//① temp 是p的后继
p->next = temp;
//② temp 的前驱是p
temp->pre = p;
//③ p 要记录最后的结点的位置,方便下一次插入
p = temp;
}
return SUCCESS;
}
//增
STATUS ListInsert(LinkList *L,int index,Element data) {
//1.插入位置不合法,为0或负数
if (index < -1) {
return ERROR;
}
//2.新建结点
LinkList temp = (LinkList)malloc(sizeof(Node));
temp->data = data;
//3.找到插入位置前一个结点
LinkList p = *L;/*临时变量 方便操作*/
for (int i = 1; i < index; i ++) {
p = p->next;
}
//4.如果插入位置超过链表本身长度
if (p == NULL) {
return ERROR;
}
//5.判断插入位置是否为最后一位
if (p->next == NULL) {
p->next = temp;
temp->pre = p;
temp->next = NULL;
} else {
//先将p的next与temp的关联
p->next->pre = temp;
temp->next = p->next;
//然后将p的与temp的关联
p->next = temp;
temp->pre = p;
}
return SUCCESS;
}
//删除
STATUS ListDelete(LinkList *L,int index,Element *e) {
//1.删除位置不合法,为0或负数
if (index < 1) {
return ERROR;
}
//2.判断双向链表是否为空,如果为空则返回ERROR;
if (*L == NULL) {
return ERROR;
}
//3.找到删除位置前一个结点
int k = 1;
LinkList p = (*L);/*临时变量 方便操作*/
while (k < index && p != NULL) {
p = p->next;
k++;
}
//4.如果k>i 或者 p == NULL 则返回ERROR
if (k > index || p == NULL) {
return ERROR;
}
//5.创建临时指针delTemp 指向要删除的结点,并将要删除的结点的data 赋值给*e,带回到main函数
LinkList tempD = p->next;
*e = tempD->data;
//6.p->next 等于要删除的结点的下一个结点
p->next = tempD->next;
//7.如果删除结点的下一个结点不为空,则将将要删除的下一个结点的前驱指针赋值p;
if (tempD->next !=NULL) {
tempD->next->pre = p;
}
//8.删除tempD
free(tempD);
return SUCCESS;
}
//删除指定元素
STATUS ListDeleteVal(LinkList *L,Element data) {
LinkList p = *L;
//1.遍历
while (p) {
//2.判断当前结点的数据域和data是否相等,若相等则删除该结点
if (p->data == data) {
//修改被删除结点的前驱结点的后继指针,
p->pre->next = p->next;
//修改被删除结点的后继结点的前驱指针
if (p->next != NULL) {
p->next->pre = p->pre;
}
//释放p
free(p);
//退出循环
break;
}
p = p->next;
}
return SUCCESS;
}
//改
STATUS ListChange(LinkList *L,int index,Element data) {
//1.删除位置不合法,为0或负数
if (index < 1) {
return ERROR;
}
//2.判断双向链表是否为空,如果为空则返回ERROR;
if (*L == NULL) {
return ERROR;
}
//3.找到要修改的node
LinkList p = (*L)->next;
int k = 1;
for (int i = 1; i < index && p->next != NULL; i ++) {
p = p->next;
k ++;
}
//4.如果位置超过链表长度,那么就不再修改
if (k != index) {
return ERROR;
}
p->data = data;
return SUCCESS;
}
//查
STATUS ListFind(LinkList *L,int index,Element *data) {
//1.位置不合法,为0或负数
if (index < 1) {
return ERROR;
}
//2.判断双向链表是否为空,如果为空则返回ERROR;
if (*L == NULL) {
return ERROR;
}
//3.找到要查找的node
LinkList p = (*L)->next;
int k = 1;
for (int i = 1; i < index && p->next != NULL; i ++) {
p = p->next;
k ++;
}
//4.如果位置超过链表长度,那么就不再查找
if (k != index) {
return ERROR;
}
*data = p->data;
return SUCCESS;
}
int main(int argc, const char * argv[]) {
// insert code here...
printf("Hello, World!\n");
STATUS status;
LinkList L;
status = ListCreat(&L);
show(L);
printf("请输入插入的位置和数据:");
Element insertData;
int insertIndex;
scanf("%d %d",&insertIndex,&insertData);
status = ListInsert(&L, insertIndex, insertData);
show(L);
printf("请输入删除的位置:\n");
Element deleteData;
int deleteIndex;
scanf("%d",&deleteIndex);
status = ListDelete(&L, deleteIndex, &deleteData);
show(L);
printf("请输入你要删除的内容\n");
scanf("%d",&deleteData);
status = ListDeleteVal(&L, deleteData);
printf("删除指定data域等于%d的结点,双向链表:\n",deleteData);
show(L);
ListChange(&L, 11, 20);
show(L);
ListChange(&L, 2, 99);
show(L);
Element findData;
ListFind(&L, 5, &findData);
printf("位置%d对应的数据是:%d\n",5,findData);
Element findData1;
ListFind(&L, 22, &findData1);
printf("位置%d对应的数据是:%d\n",22,findData1);
return 0;
}