双链表

#include <stdio.h>
#include <stdlib.h>

typedef struct dlink {
	int key;
	struct dlink *prev;
	struct dlink *next;
}DLNode, *DLIST;

DLNode *DListSearch(DLIST dl, int key)
{
	DLNode *p = dl;
	while (p != NULL && p->key != key) 
		p = p->next;

	return p;
}

// 想办法优化一下
DLIST DListInsert(DLIST dl, DLNode *x)
{
	DLNode *p = dl;

	if (p == NULL) { // Case 1:dl为空
		dl = x;
		return dl;
	}

	while (p->key < x->key && p->next != NULL)
		p = p->next;

	if (p->key < x->key && p->next == NULL) { // case 4:在dl最后插入
		x->next = p->next;
		x->prev = p;
		p->next = x;
	} else { 
		x->next = p;
		x->prev = p->prev; 
		if (p->prev == NULL) // case 2:在dl最前插入 
			dl = x;
		else                 // case 3:在dl中间插入
			p->prev->next = x;
		p->prev = x;
	}

	return dl;
}

DLIST DListDelete(DLIST dl, DLNode *x)
{
	if (dl == NULL) {
		printf("The doubly linked list is empty\n");
		return NULL;
	}

	if (x->prev != NULL) 
		x->prev->next = x->next;
	else // 删除链表第一个元素
		dl = x->next;	
	if (x->next != NULL)
		x->next->prev = x->prev;
	
	free(x);
	return dl;
}

void DListPrint(DLIST dl)
{
	DLNode *p = dl;
	while (p != NULL) {
		printf("%d\t", p->key);
		p = p->next;
	}
	printf("\n");
}

#ifndef NIL
#define NIL 0
#endif
// A circular, doubly linked list with a sentinel
DLIST CDListInit()
{
	// 开辟一个哑结点作为哨兵
	DLNode *dl = (DLNode *)malloc(sizeof(DLNode));
	if (!dl) {
		printf("dl malloc error\n");
		return NULL;
	}
	dl->key = NIL;
	dl->prev = dl->next = dl;

	return dl;
}

DLNode *CDListSearch(DLIST dl, int key)
{
	DLNode *p = dl->next;
	while (p != dl && key != p->key)
		p = p->next;

	return p;
}

DLIST CDListInsert(DLIST dl, DLNode *x)
{
	DLNode *p = dl->next;

	// 在p后插入x
// 	if (p == dl) { 可合并到下面的情况中去
// 		x->next = p->next;
// 		x->prev = p;
// 		p->next->prev = x;
// 		p->next = x;
// 	} 
//	else
	{
		while (p != dl && p->key < x->key)
			p = p->next;
		// 在p前插入x
		x->next = p;
		x->prev = p->prev;
		p->prev->next = x;
		p->prev = x;
	}

	return dl;
}

DLIST CDListDelete(DLIST dl, DLNode *x)
{
	x->prev->next = x->next;
	x->next->prev = x->prev;

	return dl;
}

void CDListPrint(DLIST dl)
{
	DLNode *p = dl->next;
	while (p != dl) {
		printf("%d\t", p->key);
		p = p->next;
	}
	printf("\n");
}

int main()
{
	int arr[] = {34, 3, 223, 678, 1, 8, 43, 87, 1234};
	int len = sizeof(arr) / sizeof(arr[0]);
	DLIST dl = NULL;

	dl = CDListInit();
	printf("Insert:\n");
	for (int i = 0; i < len; i++) {
		DLNode *p = (DLNode *)malloc(sizeof(DLNode));
		if (!p) {
			printf("p malloc error\n");
			return -1;
		}
		p->key = arr[i];
		p->prev = p->next = NULL;
		dl = CDListInsert(dl, p);
		CDListPrint(dl);
	}

	printf("Delete:\n");
	for (int i = 0; i < len; i++) {
		dl = CDListDelete(dl, DListSearch(dl, arr[i]));
		CDListPrint(dl);
	}

	system("pause");
	return 0;
}

你可能感兴趣的:(双链表)