記錄一些認爲不錯的數據結構程序算法

逆轉鏈表:
#include<stdio.h>
#include<stdlib.h>
typedef struct nod
{
	int data;
	struct nod* next;
}nod;

typedef struct list
{
	nod* top;
	nod* last;
	int cnt;
}list;

list* create()
{
	list* p = (list*)malloc(sizeof(list));
	p->top = NULL;
	p->last = NULL;
	p->cnt = 0;
	return p;
}
nod* createnod(int data)
{
	nod* p = (nod*)malloc(sizeof(nod));
	p->data = data;
	p->next = NULL;
	return p;
}
int full(list* ps)
{
	return 0;
}
int empty(list* ps)
{
	return ps->cnt == 0;
}
void pushead(list* ps, int data)
{
	if (full(ps) == 0)
	{
		nod* p = createnod(data);
		if (ps->top == NULL)
		{
			ps->top = p;
			ps->last = p;
		}
		else
		{
			p->next = ps->top;
			ps->top = p;

		}
		ps->cnt++;
	}
}

void travel(list* ps)
{
	nod* p = ps->top;
	printf("目前元素有:");
	int i;
	for (i = 0; i<ps->cnt; i++)
	{
		printf("%d ", p->data);
		p = p->next;
	}
	p = NULL;
}
void reversenod(nod* p)  //先將p指到倒數第二個節點位置,主要利用遞歸,可以將指針p一直向上移動
{
	if (p->next != NULL)
	{
		reversenod(p->next);//遞歸!
		p->next->next = p;
		p->next = NULL;  //主要爲了在頭結點的時候使用
	}
}
void reverse(list* ps)
{
	nod* p = ps->top;
	reversenod(p);
	ps->top = ps->last; //將鏈表的頭結點,尾節點位置重新分配好
	ps->last = p;
}
void main()
{
	int i;
	list* ps = create(); //創建一個空鏈表
	for (i = 0; i<5; i++)
		pushead(ps, i); //在鏈表中放五個節點
	travel(ps); //遍歷鏈表中所有元素 打印出來
	reverse(ps);//逆轉鏈表 重點
	travel(ps);

}

本人在寫reverse()程序時的代碼:
    多用了一個loc()函數,確定每一個節點的位置;利用for()將p指向倒數第二個節點,程序不簡短。
nod* loc(list* ps,int loc)
{
	nod* p=ps->top;
	int i;
	if(loc==0)
		p=NULL;
	else
	{
		for(i=0;i<loc-1;i++)
		{
		p=p->next;
		}
	
	}
	return p;
}
reverse(list* ps)
{
	int i;
	nod* p=ps->last;
	for(i=0;i<ps->cnt;i++)
	{
	p->next=loc(ps,4-i);
	p=p->next;
	}
	ps->top=p;
	p=NULL;
}

二叉樹的增加節點以及清除節點:主要利用了二級指針,就像當你將一個值傳入一個局部函數,但不僅僅是利用這個值而是想要改變這個值的時候,要用到一級指針,當你想要改變一個值的地址時,要用到二級指針。
  二叉樹的主要思想也是遞歸。
#include<stdio.h>
#include<stdlib.h>
typedef struct nod
{
	int data;
	struct nod* left;
	struct nod* right;
}nod;
typedef struct tree
{
	nod* root;
	int cnt;
}tree;

void insert_nod(nod** root, nod* pn)
{
	if (*root == NULL)             //每次遞歸都是將左右節點的地址傳進來,而如果左右節點的地址是NULL,我們本意是想要改變這個值,因此不能直接傳地址,而是要傳地址的地址,即二級指針
		*root = pn;					
	if (pn->data>(*root)->data)
		insert_nod((&(*root)->right), pn);
	if (pn->data<(*root)->data)
		insert_nod((&(*root)->left), pn);
}
void insert(tree* tree, int data)
{
	nod* pn = (nod*)malloc(sizeof(nod));
	pn->data = data;
	pn->left = pn->right = NULL;
	insert_nod(&tree->root, pn);
	tree->cnt++;
}

void tree_nod(nod* root)
{
	if (root->left != NULL)
		tree_nod(root->left);
	printf("%d  ", root->data);
	if (root->right != NULL)
		tree_nod(root->right);
}
void travel(tree* tree)
{
	if (tree->root == NULL)
		printf("爲空");
	else
		tree_nod(tree->root);
}
void clear_nod(nod** nod)
{
	if (*nod != NULL)
	{
		clear_nod(&(*nod)->left);
		clear_nod(&(*nod)->right);//確保左右都已經清理完畢
		free(*nod);
		*nod = NULL;  
	}
}
void clear(tree* tree)
{
	if (tree->root != NULL)
		clear_nod(&tree->root);
	tree->cnt = 0;
}
void main()
{
	tree tree;
	tree.root = NULL;
	tree.cnt = 0;
	int i;
	int arr[10] = { 60, 50, 20, 80, 70, 90, 10, 30, 40 };
	for (i = 0; i<10; i++)
		insert(&tree, arr[i]);
	travel(&tree);
	clear(&tree);
	travel(&tree);
}


發佈了37 篇原創文章 · 獲贊 23 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章