雙鏈表

来源:https://www.cnblogs.com/hujunxiang98/archive/2020/06/04/13046804.html
-Advertisement-
Play Games

雙向鏈表的實現 創建3個文件:doubleLinked.h、doubleLinked.c、doubleLinkedTest.c doubleLinked.h #ifndef DOUBLE_LINKED_H_ #define DOUBLE_LINKED_H_ #ifdef lxx_gnuc #defi ...


雙向鏈表的實現




創建3個文件:doubleLinked.h、doubleLinked.c、doubleLinkedTest.c




doubleLinked.h
#ifndef DOUBLE_LINKED_H_
#define DOUBLE_LINKED_H_

#ifdef __GNUC__
	#define DEPRECATED __attribute__( (deprecated) )
#elif defined(_MSC_VER)
	#define DEPRECATED __declspec( deprecated )
#else
	#define DEPRECATED
#endif

#ifndef PTOI
	#define PTOI( p ) ((int32_t)(int64_t)(p))
#endif
#ifndef ITOP
	#define ITOP( i ) ((void *)(int64_t)(i))
#endif

#define ADT DoubleLinked

#define addFirstDoubleLinked    addHeadDoubleLinked
#define addLastDoubleLinked     addTailDoubleLinked
#define setFirstDoubleLinked    setHeadDoubleLinked
#define setLastDoubleLinked     setTailDoubleLinked
#define removeFirstDoubleLinked removeHeadDoubleLinked
#define removeLastDoubleLinked  removeTailDoubleLinked
#define getFirstDoubleLinked    getHeadDoubleLinked
#define getLastDoubleLinked     getTailDoubleLinked


// 功能: a與b的比較過程.
// 參數: a, b.
// 返回: a>b返回正數, a<b返回負數, 否則返回0.
// 註意: a!=NULL且b=NULL時返回正數, a=NULL且b!=NULL時返回負數, a=b=NULL時返回0.
typedef int ( CompareFunc )( const void *a, const void *b );

typedef struct NodeDoubleLinked DoubleLinked;


// 功能: 創建新的鏈表.
// 參數: 無.
// 返回: 新的鏈表.
// 註意: 當 記憶體分配失敗 時將錯誤退出程式.
extern ADT *newDoubleLinked( void );

// 功能: 將用戶數據加入到鏈表的指定索引位置.
// 參數: list(鏈表對象的指針), index(索引位置), data(用戶數據).
// 返回: 被加入到鏈表的用戶數據.
// 註意: 索引位置從0開始計算.
//       當 list=NULL 或 index<0 或 index>=表尾索引 時將錯誤退出程式.
extern void *addDoubleLinked( ADT *list, int32_t index, void *data );

// 功能: 將用戶數據加入到鏈表的表頭.
// 參數: list(鏈表對象的指針), data(用戶數據).
// 返回: 被加入到鏈表表頭的用戶數據.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern void *addHeadDoubleLinked( ADT *list, void *data );

// 功能: 將用戶數據加入到鏈表的表尾.
// 參數: list(鏈表對象的指針), data(用戶數據).
// 返回: 被加入到鏈表表尾的用戶數據.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern void *addTailDoubleLinked( ADT *list, void *data );

// 功能: 設置鏈表的指定索引位置的用戶數據.
// 參數: list(鏈表對象的指針), index(索引位置), data(新用戶數據).
// 返回: 被加入到鏈表的用戶數據.
// 註意: 索引位置從0開始計算.
//       當 list=NULL 時將錯誤退出程式.
//       當 index<0 或 index>表尾索引 時分別新建鏈表表頭或表尾用來放置 data.
extern void *setDoubleLinked( ADT *list, int32_t index, void *data );

// 功能: 設置鏈表表頭的用戶數據.
// 參數: list(鏈表對象的指針), data(新用戶數據).
// 返回: 被加入到鏈表表頭的用戶數據.
// 註意: 當 list=NULL 時將錯誤退出程式.
//       是 空鏈表狀態 時新建鏈表表頭用來放置 data.
extern void *setHeadDoubleLinked( ADT *list, void *data );

// 功能: 設置鏈表表尾的用戶數據.
// 參數: list(鏈表對象的指針), data(新用戶數據).
// 返回: 被加入到鏈表表尾的用戶數據.
// 註意: 當 list=NULL 時將錯誤退出程式.
//       是 空鏈表狀態 時新建鏈表表尾用來放置 data.
extern void *setTailDoubleLinked( ADT *list, void *data );

// 功能: 移除鏈表指定索引位置的用戶數據.
// 參數: list(鏈表對象的指針), index(索引位置).
// 返回: 被移除的用戶數據.
// 註意: 索引位置從0開始計算.
//       當 list=NULL 或 index<0 或 index>表尾索引 或 是空鏈表狀態 時將錯誤退出程式.
extern void *removeDoubleLinked( ADT *list, int32_t index );

// 功能: 移除鏈表表頭的用戶數據.
// 參數: list(鏈表對象的指針).
// 返回: 被移除的鏈表表頭的用戶數據.
// 註意: 當 list=NULL 或 是空鏈表狀態 時將錯誤退出程式.
extern void *removeHeadDoubleLinked( ADT *list );

// 功能: 移除鏈表表尾的用戶數據.
// 參數: list(鏈表對象的指針).
// 返回: 被移除的鏈表表頭的用戶數據.
// 註意: 當 list=NULL 或 是空鏈表狀態 時將錯誤退出程式.
extern void *removeTailDoubleLinked( ADT *list );

// 功能: 偷看鏈表指定索引位置的用戶數據.
// 參數: list(鏈表對象的指針), index(索引位置).
// 返回: 鏈表指定索引位置的用戶數據.
// 註意: 索引位置從0開始計算.
//       當 list=NULL 或 index<0 或 index>表尾索引 或 是空鏈表狀態 時將錯誤退出程式.
extern void *getDoubleLinked( ADT *list, int32_t index );

// 功能: 偷看鏈表表頭的用戶數據.
// 參數: list(鏈表對象的指針).
// 返回: 鏈表表頭的用戶數據.
// 註意: 當 list=NULL 或 是空鏈表狀態 時將錯誤退出程式.
extern void *getHeadDoubleLinked( ADT *list );

// 功能: 偷看鏈表表尾的用戶數據.
// 參數: list(鏈表對象的指針).
// 返回: 鏈表表尾的用戶數據.
// 註意: 當 list=NULL 或 是空鏈表狀態 時將錯誤退出程式.
extern void *getTailDoubleLinked( ADT *list );

// 功能: 鏈表中所有用戶數據中是否包含了data.
// 參數: list(鏈表對象的指針), data(需查找的用戶數據), cmp(比較函數的指針).
// 返回: 包含data返回1, 否則返回0.
// 註意: 當 list=NULL 或 cmp=NULL 時將錯誤退出程式.
extern int existDoubleLinked( ADT *list, void *data, CompareFunc *cmp );

// 功能: 從鏈表表頭至鏈表表尾方向查找data.
// 參數: list(鏈表對象的指針), data(需查找的用戶數據), cmp(比較函數的指針).
// 返回: 包含data, 返回data所在位置, 否則返回-1.
// 註意: 當 list=NULL 或 cmpNULL 時將錯誤退出程式.
extern int32_t findDoubleLinked( ADT *list, void *data, CompareFunc *cmp );

// 功能: 從鏈表表尾至鏈表表頭方向查找data.
// 參數: list(鏈表對象的指針), data(需查找的用戶數據), cmp(比較函數的指針).
// 返回: 包含data, 返回data所在位置, 否則返回-1.
// 註意: 當 list=NULL 或 cmp=NULL 時將錯誤退出程式.
extern int32_t findTailDoubleLinked( ADT *list, void *data, CompareFunc *cmp );

// 功能: 鏈表實際已使用大小.
// 參數: list(鏈表對象的指針).
// 返回: 鏈表實際已使用大小.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern int32_t sizeDoubleLinked( ADT *list );

// 功能: 空鏈表狀態.
// 參數: list(鏈表對象的指針).
// 返回: 是空鏈表返回1, 否則返回0.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern int emptyDoubleLinked( ADT *list );

// 功能: 反轉鏈表.
// 參數: list(鏈表對象的指針).
// 返回: 無.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern void reversalDoubleLinked( ADT *list );

// 功能: 滿鏈表狀態.
// 參數: list(鏈表對象的指針).
// 返回: 是滿鏈表返回1, 否則返回0.
// 註意: 當 list=NULL 時將錯誤退出程式.
// 被棄用的函數.
extern DEPRECATED int fullDoubleLinked( ADT *list );

// 功能: 鏈表最大容量.
// 參數: list(鏈表對象的指針).
// 返回: 鏈表最大容量.
// 註意: 當 list=NULL 時將錯誤退出程式.
// 被棄用的函數.
extern DEPRECATED int32_t capacityDoubleLinked( ADT *list );

// 功能: 清空鏈表.
// 參數: list(鏈表對象的指針).
// 返回: 無.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern void clearDoubleLinked( ADT *list );

// 功能: 銷毀鏈表.
// 參數: list(存放鏈表對象的指針的指針).
// 返回: 無.
// 註意: 當 list=NULL 時將錯誤退出程式.
extern void delDoubleLinked( ADT **list );

#undef ADT

#endif

doubleLinked.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "adt.h"


// 功能: 列印錯誤信息後就錯誤退出程式.
// 參數: expression(錯誤判斷表達式), message(需列印的錯誤信息).
// 返回: 無.
// 註意: 當表達式 expression 為真時, 才觸發.
#define ERROR_EXIT( expression, message )                                    \
if( (expression) ) {                                                         \
	fprintf( stderr, "\nerror location: file = %s, func = %s, line = %d.\n", \
	                       __FILE__, __func__, __LINE__ );                   \
	fprintf( stderr, "error  message: %s%s.\n\a",                            \
	                       (message) != NULL ? (message) : __func__,         \
		                   (message) != NULL ? "" : " function error" );     \
	exit( EXIT_FAILURE );                                                    \
}

// 功能: 分配記憶體, 與 malloc 功能一樣.
// 參數: p(傳入傳出參數), size(位元組).
// 返回: 無, 實際通過參數p進行傳出.
// 註意: 當 記憶體分配失敗 時將錯誤退出程式.
#define NEW( p, size ) ({                              \
	ERROR_EXIT( (p) == NULL, "NullPointerException" ); \
	*(p) = malloc( (size) );                           \
	ERROR_EXIT( *(p) == NULL, "OutOfMemoryError" );    \
})

// 功能: 分配記憶體並把每個位元組置0, 與 calloc 功能一樣.
// 參數: p(傳入傳出參數), size(位元組), n(數量).
// 返回: 無, 實際通過參數p進行傳出.
// 註意: 當 記憶體分配失敗 時將錯誤退出程式.
#define NEW0( p, nE, sizeofE ) ({                             \
	ERROR_EXIT( (p) == NULL, "NullPointerException" );        \
	ERROR_EXIT( (nE) < 0, "Parameter 'nE' Error" );           \
	ERROR_EXIT( (sizeofE) < 0, "Parameter 'sizeofE' Error" ); \
	*(p) = calloc( nE, sizeofE );                             \
	ERROR_EXIT( *(p) == NULL, "OutOfMemoryError" );           \
})

#define DEL( p ) ({                     \
	if( (p) != NULL && *(p) != NULL ) { \
		free( *(p) );                   \
		*(p) = NULL;                    \
	}                                   \
})

#define ADT DoubleLinked


typedef struct NodeDoubleLinked {
	void *data;
	struct NodeDoubleLinked *prev;
	struct NodeDoubleLinked *next;
} Node, DoubleLinked;


ADT *newDoubleLinked( void ) {
	ADT *list = NULL;

	NEW0( &list, 1, sizeof(*list) );

	return list;
}

void *addDoubleLinked( ADT *list, int32_t index, void *data ) {
	Node *indexN = NULL, *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( index < 0 || index > PTOI( list->data ), "IndexOutOfBoundsException" );
	for( indexN = list->next; --index >= 0; indexN = indexN->next ) {}
	NEW( &node, sizeof(*node) );
	node->data = data;
	node->next = indexN;
	if( indexN != NULL ) {
		node->prev = indexN->prev;
		if( indexN->prev != NULL ) {
			indexN->prev->next = node;
		}
		indexN->prev = node;
	} else {
		node->prev = list->prev;
		if( list->prev != NULL ) {
			list->prev->next = node;
		}
		list->prev = node;
	}
	list->next = list->next != indexN ? list->next : node;
	list->next = list->next != NULL ? list->next : node;
	list->data = ITOP( PTOI( list->data ) + 1 );

	return data;
}

void *addHeadDoubleLinked( ADT *list, void *data ) {
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	NEW( &node, sizeof(*node) );
	node->data = data;
	node->prev = NULL;
	node->next = list->next;
	if( list->next != NULL ) {
		list->next->prev = node;
	}
	list->prev = list->prev != NULL ? list->prev : node;
	list->next = node;
	list->data = ITOP( PTOI( list->data ) + 1 );

	return data;
}

void *addTailDoubleLinked( ADT *list, void *data ) {
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	NEW( &node, sizeof(*node) );
	node->data = data;
	node->prev = list->prev;
	node->next = NULL;
	if( list->prev != NULL ) {
		list->prev->next = node;
	}
	list->next = !list->next ? node : list->next;
	list->prev = node;
	list->data = ITOP( PTOI( list->data ) + 1 );

	return data;
}

void *setDoubleLinked( ADT *list, int32_t index, void *data ) {
	Node *indexN = NULL;
	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( index < 0 || index > PTOI( list->data ), "IndexOutOfBoundsException" );
	for( indexN = list->next; --index >= 0; indexN = indexN->next ) {}

	return indexN->data = data;
}

void *setHeadDoubleLinked( ADT *list, void *data ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );

	return list->next->data = data;
}

void *setTailDoubleLinked( ADT *list, void *data ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );

	return list->prev->data = data;
}

void *removeDoubleLinked( ADT *list, int32_t index ) {
	void *data = NULL;
	Node *indexN = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( index < 0 || index >= PTOI( list->data ), "IndexOutOfBoundsException" );
	for( indexN = list->next; --index >= 0; indexN = indexN->next ) {}
	if( indexN->prev != NULL ) {
		indexN->prev->next = indexN->next;
	}
	if( indexN->next != NULL ) {
		indexN->next->prev = indexN->prev;
	}
	list->next = list->next != indexN ? list->next : indexN->next;
	list->prev = list->prev != indexN ? list->prev : indexN->prev;
	list->data = ITOP( PTOI( list->data ) - 1 );
	data = indexN->data;
	DEL( &indexN );

	return data;
}

void *removeHeadDoubleLinked( ADT *list ) {
	void *data = NULL;
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );
	node = list->next;
	if( node->next != NULL ) {
		node->next->prev = node->prev;
	}
	list->prev = list->prev != node ? list->prev : NULL; // 只有一個節點時.
	list->next = node->next;
	list->data = ITOP( PTOI( list->data ) - 1 );
	data = node->data;
	DEL( &node );

	return data;
}

void *removeTailDoubleLinked( ADT *list ) {
	void *data = NULL;
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );
	node = list->prev;
	if( node->prev != NULL ) {
		node->prev->next = node->next;
	}
	list->prev = node->prev;
	list->next = list->next != node ? list->next : NULL; // 只有一個節點時.
	list->data = ITOP( PTOI( list->data ) - 1 );
	data = node->data;
	DEL( &node );

	return data;
}

void *getDoubleLinked( ADT *list, int32_t index ) {
	Node *indexN = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( index < 0 || index >= PTOI( list->data ), "IndexOutOfBoundsException" );
	for( indexN = list->next; --index >= 0; indexN = indexN->next ) {}

	return indexN->data;
}

void *getHeadDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );

	return list->next->data;
}

void *getTailDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( PTOI( list->data ) < 1, "EmptyContainerError" );

	return list->prev->data;
}

int existDoubleLinked( ADT *list, void *data, CompareFunc *cmp ) {
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( !cmp, "NullPointerException" );
	for( node = list->next; node; node = node->next ) {
		if( !cmp( node->data, data ) ) {
			return 1;
		}
	}

	return -1;
}

int32_t findDoubleLinked( ADT *list, void *data, CompareFunc *cmp ) {
	int32_t i = 0;
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( !cmp, "NullPointerException" );
	for( node = list->next; node != NULL; node = node->next ) {
		if( !cmp( node->data, data ) ) {
			break;
		}
		++i;
	}

	return i >= PTOI( list->data ) ? -1 : i;
}

int32_t findTailDoubleLinked( ADT *list, void *data, CompareFunc *cmp ) {
	int32_t i = 0;
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	ERROR_EXIT( cmp == NULL, "NullPointerException" );
	for( node = list->prev; node != NULL; node = node->prev ) {
		if( !cmp( node->data, data ) ) {
			break;
		}
		++i;
	}

	return PTOI( list->data ) - 1 - i;
}

int32_t sizeDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );

	return PTOI( list->data );
}

int emptyDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );

	return PTOI( list->data ) < 1;
}

static void reverse( Node *node ) {
	Node *t = NULL;

	if( node == NULL ) {
		return;
	}
	reverse( node->next );
	t = node->prev;
	node->prev = node->next;
	node->next = t;
}
void reversalDoubleLinked( ADT *list ) {
	Node *p1 = NULL, *p2 = NULL, *p3 = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	#if 1
	for( p2 = list; p2 != NULL; p2 = p3 ) { // 調換prev與next指針.
		p3 = p2->next;
		p1 = p2->next;
		p2->next = p2->prev;
		p2->prev = p1;
	}
	#else
	list->prev = list->next;
	for( p2 = list->next; p2 != NULL; p2 = p3 ) { // 三指針反轉鏈表.
		p3 = p2->next;
		p2->next = p1;
		p2->prev = NULL;
		if( p1 != NULL ) {
			p2->prev = p1->prev;
			p1->prev = p2;
		}
		p1 = p2;
	}
	list->next = p1;
	#endif
	if( 0 ) reverse( list );
}

int fullDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );

	return 0;
}

int32_t capacityDoubleLinked( ADT *list ) {
	ERROR_EXIT( list == NULL, "NullPointerException" );

	return INT32_MAX;
}

void clearDoubleLinked( ADT *list ) {
	Node *c = NULL, *t = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	for( c = list->next; c != NULL; c = t ) {
		t = c->next;
		DEL( &c );
	}
	list->data = ITOP( 0 );
	list->next = NULL;
	list->prev = NULL;
}

void delDoubleLinked( ADT **list ) {
	Node *c = NULL, *t = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	for( c = (*list)->next; c != NULL; c = t ) {
		t = c->next;
		DEL( &c );
	}
	DEL( list );
}

void addressDoubleLinked( ADT *list ) {
	Node *node = NULL;

	ERROR_EXIT( list == NULL, "NullPointerException" );
	printf( "next[" );
	for( node = list->next; node != NULL; node = node->next ) {
		printf( "%5d%s", *(int32_t *) node->data, !node->next ? "" : "->" );
	}
	printf( "]\n" );
	printf( "prev[" );
	for( node = list->prev; node != NULL; node = node->prev ) {
		printf( "%5d%s", *(int32_t *) node->data, !node->prev ? "" : "<-" );
	}
	printf( "]\n" );
	printf( "list->next = %d, ", !list->next ? INT_MIN : *(int32_t *) list->next->data );
	printf( "list->prev = %d\n", !list->prev ? INT_MIN : *(int32_t *) list->prev->data );
}

doubleLinkedTest.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#include "doubleLinked.h"


// 功能: 對數組的某一區間內的元素值進行隨機化.
// 參數: a(數組首地址), left(左閉區間), right(右閉區間), v(最大隨機值).
// 返回: 無.
// 註意: 當v是正數/負數/零時,隨機值的區間分別為[-v, v]/[]/[].
static void randomArray( int32_t a[], int32_t left, int32_t right, int32_t v ) {
	v -= v != INT32_MAX ? 0 : 1;
	while( left <= right ) {
		a[left++] = rand() % (v + 1) - rand() % (v + 1);
	}
}

// 功能: 將數組的某一區間內的元素值送入到文件流中.
// 參數: a(數組首地址), left(左閉區間), right(右閉區間), fp(文件流指針).
// 返回: 無.
// 註意: 無.
static void printArray( const int32_t a[], int32_t left, int32_t right, FILE *fp ) {
	fprintf( fp, "[" );
	while( left <= right ) {
		fprintf( fp, "%5d%s", a[left], left != right ? ", " : "" );
		++left;
	}
	fprintf( fp, "]\n" );
}

int cmp( const void *a, const void *b ) {
	return *(int32_t *) a - *(int32_t *) b;
}

#if 0
int main( int argc, char *argv[] ) {
	int32_t *a = NULL;
	int32_t i = 0, n = 0;
	DoubleLinked *list = NULL;

	printf( "please input array length: n = " );
	scanf( "%d%*c", &n );
	printf( "\n" );

	NEW( &a, sizeof(*a) * n );

	randomArray( a, 0, n - 1, 123 );
	printArray( a, 0, n - 1, stdout );

	list = newDoubleLinked();

	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	for( i = 0; i < n; ++i ) {
		printf( "addDoubleLinked( list, %d, &a[%d] ) = %d\n", i, i, *(int32_t *) addDoubleLinked( list, i, &a[i] ) );
	}
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	for( i = 0; i < n; ++i ) {
		printf( "getDoubleLinked( list, %d ) = %d\n", i, *(int32_t *) getDoubleLinked( list, i ) );
	}
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	int32_t k = INT32_MAX;
	#if 1
	switch( 3 ) {
		case 0:
			i = 0; break;
		case 1:
			i = 1; break;
		case 2:
			i = sizeDoubleLinked( list ) - 1; break;
		case 3:
			i = sizeDoubleLinked( list ); break;
	}
	printf( "addDoubleLinked( list, %d, &k ) = %d\n", i, *(int32_t *) addDoubleLinked( list, i, &k ) );
	#else
	printf( "addFirstDoubleLinked( list, &k ) = %d\n", *(int32_t *) addFirstDoubleLinked( list, &k ) );
	printf( "addLastDoubleLinked( list, &k ) = %d\n", *(int32_t *) addLastDoubleLinked( list, &k ) );
	#endif
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	#if 0
	switch( 3 ) {
		case 0:
			i = 0; break;
		case 1:
			i = 1; break;
		case 2:
			i = sizeDoubleLinked( list ) - 1; break;
	}
	printf( "removeDoubleLinked( list, %d ) = %d\n", i, *(int32_t *) removeDoubleLinked( list, i ) );
	#else
	printf( "removeFirstDoubleLinked( list ) = %d\n", *(int32_t *) removeFirstDoubleLinked( list ) );
	printf( "removeLastDoubleLinked( list ) = %d\n", *(int32_t *) removeLastDoubleLinked( list ) );
	while( !emptyDoubleLinked( list ) ) {
		printf( "removeFristDoubleLinked( list ) = %d\n", *(int32_t *) removeFirstDoubleLinked( list ) );
	}
	#endif
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	#if 0
	printf( "findDoubleLinked( list, &k, cmp ) = %d\n", findDoubleLinked( list, &k, cmp ) );
	#else
	printf( "findTailDoubleLinked( list, &k, cmp ) = %d\n", findTailDoubleLinked( list, &k, cmp ) );
	#endif
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	reversalDoubleLinked( list );
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list )  = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list )  = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n" );

	delDoubleLinked( &list );
	DEL( &a );

	return EXIT_SUCCESS;
}
#else
int main( int argc, char *argv[] ) {
	int32_t n = 0, i = 0, *a = NULL;
	DoubleLinked *list = NULL;

	printf( "please input array length: n = " );
	scanf( "%d%*c", &n );
	printf( "\n" );

	NEW( &a, sizeof(*a) * n );
	randomArray( a, 0, n - 1, 321 );
	printArray( a, 0, n - 1, stdout );

	list = newDoubleLinked();

	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	for( i = 0; i < n; ++i ) {
		printf( "addDoubleLinked( list, %d, &a[%d]=%d ) = %d\n", i, i, a[i], *(int32_t *) addDoubleLinked( list, i, &a[i] ) );
	}
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	for( i = 0; i < sizeDoubleLinked( list ); ++i ) {
		printf( "getDoubleLinked( list, %d ) = %d\n", i, *(int32_t *) getDoubleLinked( list, i ) );
	}
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	int32_t k = rand();
	#if 1
	switch( 3 ) {
		case 0:
			i = 0; break;
		case 1:
			i = 1; break;
		case 2:
			i = sizeDoubleLinked( list ) - 1; break;
		case 3:
			i = sizeDoubleLinked( list ); break;
		default:
			break;
	}
	printf( "addDoubleLinked( list, %d, &k=%d ) = %d\n", i, k, *(int32_t *) addDoubleLinked( list , i, &k ) );
	#else
	printf( "addFirstDoubleLinked( list, &k=%d ) = %d\n",k, *(int32_t *) addFirstDoubleLinked( list, &k ) );
	//printf( "addLastDoubleLinked( list, &k=%d ) = %d\n", k, *(int32_t *) addLastDoubleLinked( list, &k ) );
	#endif
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", *(int32_t *) getFirstDoubleLinked( list ) );
	printf( "getLastDoubleLinked( list ) = %d\n", *(int32_t *) getLastDoubleLinked( list ) );
	printf( "\n\n" );

	#if 1
	switch( 2 ) {
		case 0:
			i = 0; break;
		case 1:
			i = 1; break;
		case 2:
			i = sizeDoubleLinked( list ) - 1; break;
	}
	printf( "removeDoubleLinked( list, %d ) = %d\n", i, *(int32_t *) removeDoubleLinked( list , i ) );
	#else
	//printf( "removeFirstDoubleLinked( list ) = %d\n", *(int32_t *) removeFirstDoubleLinked( list ) );
	printf( "removeLastDoubleLinked( list ) = %d\n", *(int32_t *) removeLastDoubleLinked( list ) );
	#endif
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	#if 0
	printf( "findDoubleLinked( list, &k ) = %d\n", findDoubleLinked( list, &k, cmp ) );
	#else
	printf( "findTailToFrontDoubleLinked( list &k ) = %d\n", findTailDoubleLinked( list, &k, cmp ) );
	#endif
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	addressDoubleLinked( list );
	printf( "reversal: " );
	reversalDoubleLinked( list );
	addressDoubleLinked( list );
	printf( "emptyDoubleLinked( list ) = %s\n", emptyDoubleLinked( list ) ? "true" : "false" );
	printf( "sizeDoubleLinked( list ) = %d\n", sizeDoubleLinked( list ) );
	printf( "getFirstDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getFirstDoubleLinked( list ) : INT32_MIN );
	printf( "getLastDoubleLinked( list ) = %d\n", !emptyDoubleLinked( list ) ? *(int32_t *) getLastDoubleLinked( list ) : INT32_MIN );
	printf( "\n\n" );

	delDoubleLinked( &list );
	DEL( &a );

	return EXIT_SUCCESS;
}
#endif




您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在開發中修改第三方組件樣式是很常見,但由於 scoped 屬性的樣式隔離,可能需要去除 scoped 或是另起一個 style 。 這些做法都會帶來副作用(組件樣式污染、不夠優雅),樣式穿透在css預處理器中使用才生效。 我們可以使用 >>> 或 /deep/ 解決這一問題: <style scop ...
  • canvas 和 webGL 這兩項圖形技術結合 css3 可以說能完成絕大部分的動畫和需求。但 canvas 和 webGL 畢竟是偏向底層的繪製引擎,某些場景使用起來還是過於繁瑣的,不分場合一律使用錘子解決的行為不值得提倡。svg 在解決排版,圖標,相關動畫還是非常高效的,而且 svg 還是矢量 ...
  • 一、ODS層ODS 全稱是 Operational Data Store,一般對應的是操作性數據存儲,直接面向主題的,也叫數據運營層,通常是最接近數據源中數據的一層,數據源中的數據,經過抽取、洗凈、傳輸,也就是通常說的 ETL 之後的數據存入本層。本層的數據,總體上大多是按照源頭業務系統的分類方式而 ...
  • 一、MPP 架構 1、MPP架構的基礎概念 MPP (Massively Parallel Processing),即大規模並行處理,在資料庫非共用集群中,每個節點都有獨立的磁碟存儲系統和記憶體系統,業務數據根據資料庫模型和應用特點劃分到各個節點上,每台數據節點通過專用網路或者商業通用網路互相連接,彼 ...
  • 背景 有人對Java主流鎖做了下麵全面的梳理。梳理的確實挺好的。但是我看到這張圖,第一個感覺是:記不住。 因為分了太多類,彼此之間沒有什麼聯繫。做PPT可以。如果聊天或者面試,不用紙筆的情況下,就不太好描述了。也不利於對原理和應用的理解。 基於上述的考慮,我就自己系統的梳理一下鎖,希望可以有助於大家 ...
  • 一、使用反射機制來 (1)獲取一個類; (2)獲取類的構造函數 (3)通過構造函數來獲取一個對象 package com.bjpowernode.java_learning; import java.lang.reflect.*; ​ public class D120_1_ConstructerO ...
  • 本教程源碼請訪問:tutorial_demo 一、AOP概述 1.1、概念 AOP:全稱是Aspect Oriented Programming,即:面向切麵編程。 通過預編譯方式和運行期間動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中 ...
  • 本篇主要討論的是不同存儲結構(主要是LSM-tree和B-tree),它們應對的不同場景,所採用的底層存儲結構,以及對應用以提升效率的索引。 所謂資料庫,最基礎的功能,就是保存數據,並且在需要的時候可以方便地檢索到需要的數據。在這個基礎上,演化出了不同的資料庫系統,以及多種索引機制幫助檢索數據。這篇 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...