Thursday, November 08, 2012

C範例程式 : 鍊結串列 linked list

使用結構(struct)實作節點(node). 串列建立在主程式中, 使用 nodep * 型態傳進函式進行 push 及 pop.
程式碼 include stdio.h stdlib.h

#define DIRTYPE 8

// Define structure pointer
typedef struct node * nodep;

// Define structure
struct node {
	int x;
	int y;
	int dir;
	nodep next;
};

// Add new node to linked list : addr. of head, addr. of tail, new node
void pushnode(nodep*,nodep*,nodep);
// Pop end node of linked list : addr. of head, addr. of tail
void popendnode(nodep*,nodep*);
// Pop begin node of linked list : addr. of head, addr. of tail
void popheadnode(nodep*,nodep*);
// Show linked list from begin to end
void show(nodep);

int main()
{
	nodep head = NULL;
	nodep tail = NULL;
	nodep tmp  = NULL;
	int tx, ty, td, nc = 0;
	int clean = 0;

	while(1)
	{
		tmp = (nodep)malloc(sizeof(struct node));

		printf("請輸入三個正整數 X座標 Y座標 方向 (輸入 0 0 0 結束程式) ");

		scanf("%d %d %d", &tx, &ty, &td);

		if(!tx && !ty && !td)
		{
			printf("選擇結束程式.\n");
			break;
		}

		tmp->x=tx;
		tmp->y=ty;
		tmp->dir=td%DIRTYPE;
		tmp->next=NULL;

		pushnode(&head, &tail, tmp);
		nc++;

		printf("======   串列成員如下   ======\n");
		show(head);
		printf("======      ======      ======\n");
	}

	if(!nc)
		exit(0);

	printf("======  串列最終成員如下 ======\n");
	show(head);
	printf("======      ======      ======\n");

	printf("請問如何清除串列 : \n 1) 從尾端清除 \n 2) 從頭端清除 ");
	scanf("%d", &clean);

	if(clean != 1 && clean != 2)
	{
		clean = 1;
		printf("選項錯誤 使用預設 從尾端清除 \n");
	}

	printf("\n清除串列\n");
	for(int i = nc; i > 0; i--)
	{
		if(clean == 1)
			popendnode(&head, &tail);
		else
			popheadnode(&head, &tail);

                printf("\n======   串列成員如下   ======\n");
                show(head);
                printf("======      ======      ======\n\n");

		//if(!tail)
		//	head = tail;

		//if(!head)
		//	tail = head;
	}
	printf("清除串列完畢\n");

	printf("\n======  串列最終成員如下 ======\n");
	show(head);
	printf("======      ======      ======\n");

	return 0;
}

void pushnode(nodep *h, nodep *t, nodep n)
{
	//printf(" push node \n");

	if(!*h)
	{
		//printf(" add to empty list \n");
		*h = n;
		*t = n;
	}
	else
	{
		//printf(" add to non-empty list \n");
		(*t)->next = n;
		*t = n;
	}

/*	printf("h   = %x\n", h);
	printf("t   = %x\n", t);
        printf("&h   = %x\n", &h);
        printf("&t   = %x\n", &t);*/

	//return t;
}

void show(nodep h)
{
	while(h)
	{
		printf("( %d, %d )(dir = %d)\n", h->x, h->y, h->dir);
		h = h->next;
	}
}

void popendnode(nodep *h, nodep *t)
{
	nodep p, out;

	if(*h && *t)
	{
		p = *h;
		while(p != *t && p->next != *t)
			p = p->next;

		if(p->next)
		{
			out = p->next;
			*t = p;
			p->next = NULL;
		}
		else
		{
			out = p;
			*h = NULL;
			*t = NULL;
		}

		printf("倒出最後一個 node ( %d, %d )(dir = %d)\n", out->x, out->y, out->dir);
		free(out);
	}
}

void popheadnode(nodep *h, nodep *t)
{
	nodep out;

	if(*h && *t)
	{
		out = *h;
		printf("倒出第一個 node ( %d, %d )(dir = %d)\n", out->x, out->y, out->dir);
		if(out->next)
		{
			*h = out->next;
		}
		else
		{
			*h = NULL;
			*t = NULL;
		}
		free(out);
	}
}

No comments: