您的位置:首页 > 编程语言 > C#

二叉树问题C#实现

2012-09-08 09:36 253 查看
反转字符串

static string ReverseSentence(string sentence)
{
if (sentence == null)
throw new ArgumentNullException("sentence");
if (sentence.Length == 0)
return sentence;

char [] senten = new char[sentence.Length];
for (int i = 0; i < senten.Length; i++) //将整个句子反转
{
senten[i] = sentence[senten.Length-1-i];
}

int start = 0;
int length = 0;
int index = 0;
string rt = string.Empty;
char[] word;
while (index < senten.Length)
{
while (index <senten.Length) //内循环
{
if (senten[index] >= 65 && senten[index] <= 122) //若为字母,则不断对长度加一(单词是连续字母,故可以使用start+length的组合确定一个单词)
{
length++;
index++;
}
else // 非字母
{
if (length == 0) //未发现连续字母
{
start++; //调整单词开始位置start
rt += senten[index];
index++;
}
break;
}
}
if (length > 0) //统计完一个单词,对其反转
{
word = new char[length];
for (int i = start; i < start + length; i++)
{
word[i - start] = senten[i];
}
for (int i = 0; i < word.Length; i++)
{
rt += word[word.Length - i - 1];
}
start = start + length;
length = 0;
}
}
return rt;

}

二叉树的非递归遍历

  周末闲来无事,突然想到了二叉树的遍历问题,如果考虑用递归算法的话比较简单,但是如果用空间换取时间的话,考虑用辅助数据结构:栈来解决遍历的问题,代码如下:

//非递归后序遍历二叉树
static void PostOrder(BinaryTreeNode root)
{
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();

BinaryTreeNode curr = root;
while (curr != null)
{
stack.Push(curr );
curr = curr .Left;
}
BinaryTreeNode tmp = null;
BinaryTreeNode last = null;
while (stack.Count > 0)
{
tmp = stack.Peek();
if (tmp.Right == null || tmp.Right == last) //关键点:栈顶元素的右孩子为空或者为刚刚访问过的节点时才弹出并输出
{
tmp = stack.Pop();
last = tmp;
Console.WriteLine(tmp.Data);
}
else
{
tmp = tmp.Right;//右孩子不为空入栈

stack.Push(tmp);
while (tmp.Left != null)//并将右孩子的所有左子孙节点入栈
{
stack.Push(tmp.Left);
tmp = tmp.Left;
}
}
}

}

//非递归前序遍历二叉树

static void PrevOrder(BinaryTreeNode root)
{
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();

stack.Push(root);
BinaryTreeNode tmp = null;
while (stack.Count >0)
{
tmp = stack.Pop();
Console.WriteLine(tmp.Data);
if (tmp.Right != null)
stack.Push(tmp.Right); //右孩子节点不为空入栈,因为要先输出左孩子,鉴于栈的特点是先入后出,所以先入右孩子
if (tmp.Left != null)
stack.Push(tmp.Left);//左孩子节点不为空入栈

}
}

//非递归中序遍历二叉树
static void MiddleOrder(BinaryTreeNode root)
{
Stack<BinaryTreeNode> stack = new Stack<BinaryTreeNode>();

BinaryTreeNode curr = root;
while (curr!= null)
{
stack.Push(curr);
curr= curr.Left;
}
BinaryTreeNode tmp = null;
while (stack.Count > 0)
{
tmp = stack.Pop();//与后续遍历的差别是:输出的时候检测右孩子是否为空,或者右孩子是否刚刚访问过
Console.WriteLine(tmp.Data);
tmp = tmp.Right;
if (tmp != null)
{
stack.Push(tmp);
while (tmp.Left != null)
{
stack.Push(tmp.Left);
tmp = tmp.Left;
}

}
}
}

测试通过的代码:http://files.cnblogs.com/shiyulun1984/test.rar

欢迎拍砖!

单链表排序



class LinkNode
{
private LinkNode _next;

internal LinkNode Next
{
get { return _next; }
set { _next = value; }
}

private int _data;

public int Data
{
get { return _data; }
set { _data = value; }
}

public LinkNode()
{ }

public LinkNode(int data)
{
_data = data;
}

public LinkNode(int data, LinkNode next)
{
_data = data;
_next = next;
}
}


static LinkNode SortLink(LinkNode head)
{

LinkNode current = head.Next;
LinkNode next = null;
LinkNode prevCurr = head, prevNext = head.Next;

while (current != null)
{
next = current.Next;
while (next != null)
{
if (current.Data > next.Data)
{
LinkNode tmp = null;
if (current.Next == next) //key:当两个腰交换的节点相邻时记录next将要指向的地址为基准节点ajacent element exchange
tmp = current;
else
{   //要交换的几点不相邻时,记录next将要指向的地址为基准节点的下一个节点,一定要注意相邻节点的处理,否则会出现死循环
if (prevNext != null)
prevNext.Next = current;
tmp = current.Next;
}
current.Next = next.Next;
next.Next = tmp;
if (prevCurr != null)
prevCurr.Next = next;
current = next; //改变基准节点  为位置提到前面来的节点                    }

prevNext = next;
next = next.Next;
}
prevCurr = current;
current = current.Next;

}
return head;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: