ticoAg/ChineseCorpus-Kaggle-fanti huggingface dataset:
void PreOrderTraverse(BiPTree T,void(*Visit)(BiPTree))
{ /* 先序遞迴遍歷二叉樹T */
Visit(T); /* 先訪問根結點 */
PreOrderTraverse(T->lchild,Visit); /* 再先序遍歷左子樹 */
PreOrderTraverse(T->rchild,Visit); /* 最後先序遍歷右子樹 */
void InOrderTraverse(BiPTree T,void(*Visit)(BiPTree))
{ /* 中序遞迴遍歷二叉樹T */
InOrderTraverse(T->lchild,Visit); /* 中序遍歷左子樹 */
Visit(T); /* 再訪問根結點 */
InOrderTraverse(T->rchild,Visit); /* 最後中序遍歷右子樹 */
void PostOrderTraverse(BiPTree T,void(*Visit)(BiPTree))
{ /* 後序遞迴遍歷二叉樹T */
PostOrderTraverse(T->lchild,Visit); /* 後序遍歷左子樹 */
PostOrderTraverse(T->rchild,Visit); /* 後序遍歷右子樹 */
Visit(T); /* 最後訪問根結點 */
void LevelOrderTraverse(BiPTree T,void(*Visit)(BiPTree))
{ /* 層序遍歷二叉樹T(利用佇列) */
InitQueue(&q);
EnQueue(&q,T);
while(!QueueEmpty(q))
DeQueue(&q,&a);
Visit(a);
if(a->lchild!=NULL)
if(a->rchild!=NULL)
我們經常希望訪問樹中的每一個結點並且查看它的值。有很多常見的順序來訪問所有的結點，而且每一種都有有用的性質。
在深度優先順序中，我們希望從根結點訪問最遠的結點。和圖的深度優先搜索不同的是，不需記住訪問過的每一個結點，因為樹中不會有環。前序，中序和後序遍歷都是深度優先遍歷的特例。
遍歷二叉樹：L、D、R分別表示遍歷左子樹、訪問根結點和遍歷右子樹，則先(根)序遍歷二叉樹的順序是DLR，中(根)序遍歷二叉樹的順序是LDR，後(根)序遍歷二叉樹的順序是LRD。還有按層遍歷二叉樹。這些方法的時間複雜度都是O(n)，n為結點個數。
如果T2是由有序樹T轉換而來的二叉樹，那麼T中結點的前序就是T2中結點的前序，T中結點的後序就是T2中結點的中序。任何一棵二叉樹的葉結點在先序、中序和後序遍歷中的相對次序不發改變。設n,m為一棵二叉樹上的兩個結點，在中序遍歷時，n在m前的條件是n在m的左方。前序序列和中序序列相同的二叉樹為空樹或任一結點均無左孩子的非空二叉樹；中序序列和後序序列相同的二叉樹為空樹或任一結點均無右孩子的非空二叉樹；前序序列和後序序列相同的二叉樹為空樹或僅有一個結點的二叉樹。
假設我們有一個包含值的value和指向兩個子結點的left和right的樹結點結構。我們可以寫出這樣的過程：
visit(node)
print node.value
if node.left
= null then visit(node.left)
if node.right != null then visit(node.right)
這樣會用前序打印出樹中的值。在前序，每個結點在訪問它的子結點之前訪問。類似地，如果打印語句在最後，每個結點在訪問他的子節點之後訪問，樹中的值會用後序來打印。在這兩種情況中，左子樹中的值比右子樹中得值先打印。
最後，上面的中序遍歷，每個結點在訪問左子樹和右子樹之間訪問。這在遍歷二叉搜尋樹時很常用，因為它能用遞增的順序來遍歷所有的值。
為什麼呢？如果''n''是二叉搜尋樹的結點，那麼''n''的左子樹的所有結點的值都比n的值要小，而且''n''的右子樹的所有節點的值都比n的值要大。因此，如果我們順序遍歷左子樹，然後訪問''n''，然後順序遍歷右子樹。我們就已經循序存取了整個樹。
后序遍歷偽代碼如下：
在這個二叉樹中，
* 前序遍歷的結果：M，G，D，B，A，C，F，E，J，H，I，K，L，S，P，O，N，Q，R，W，U，T，V，X，Z，Y
* 後序遍歷的結果：A，C，B，E，F，D，I，H，L，K，J，G，N，O，R，Q，P，T，V，U，Y，Z，X，W，S，M
* 中序遍歷的結果：A，B，C，D，E，F，G，H，I，J，K，L，M，N，O，P，Q，R，S，T，U，V，W，X，Y，Z
以上的遞迴演算法使用與樹的高度成比例的棧空間。如果我們在每個結點中存儲指向父結點的指標，那樣可以使用反覆運算演算法，只使用常數空間實現所有這些遍歷。然而，指向父結點的指標佔用更多的空間。這只在需要指向父節點的指標或棧空間有限時才使用。例如，
這是一個中序遍歷的反覆運算演算法：
visit(root)
prev    := null
current := root
next    := null
while current != null
if prev == current.parent
prev := current
next := current.left
if next == null or prev == current.left
print current.value
next := current.right
if next == null or prev == current.right
next := current.parent
current := next
File:Bitree.JPG
用二叉樹表示下述運算式：a+b*(c-d)-e/f
*先序遍歷的序列是：-+a*b-cd/ef
*中序遍歷的序列是：a+b*c-d-e/f
*後序遍歷的序列是：abcd-*+ef/-
和深度優先遍歷不同，廣度優先遍歷會先訪問離根節點最近的節點。二叉樹的廣度優先遍歷又稱按層次遍歷。演算法借助佇列實現。
一般有序樹可映射為二叉樹，但反之未必成立。
n叉樹轉換為二叉樹的方法：二叉樹中結點x的左子結點為n叉樹中結點x的左子結點；二叉樹中結點x的右子結點為n叉樹中結點x的第一個右邊的同級結點y。
二叉樹當且僅當根節點沒有右子結點時可轉換為n叉樹。
例如，在左邊的樹中，A有6個子結點{B,C,D,E,F,G}。它能被轉換成右邊的二叉樹。
將n叉樹轉換為二叉樹的例子
*將一棵樹轉換為二叉樹的方法：
#在兄弟之間加一連線；
#對每個結點，除了其左孩子外，去除其與其餘孩子之間的聯繫；
#以樹的根結點為軸心，將整樹順時針轉45度。
樹的二叉鏈表標記法（孩子兄弟標記法）是樹和二叉樹轉換的媒介。
二叉樹與森林相互轉換的邏輯示意
/* 樹的二叉鏈表(孩子—兄弟)存儲表示 */
typedef struct CSNode
struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;
/* 樹的二叉鏈表(孩子—兄弟)存儲的基本操作(17個) */
#define ClearTree DestroyTree /* 二者操作相同 */
#include"func6-2.c" /* 包括PreOrderTraverse */
void InitTree(CSTree *T)
{ /* 操作結果：構造空樹T */
void DestroyTree(CSTree *T)
{ /* 初始條件：樹T存在。操作結果：銷毀樹T */
if(*T)
if((*T)->firstchild) /* T有長子 */
DestroyTree(&(*T)->firstchild); /* 銷毀T的長子為根結點的子樹 */
if((*T)->nextsibling) /* T有下一個兄弟 */
DestroyTree(&(*T)->nextsibling); /* 銷毀T的下一個兄弟為根結點的子樹 */
typedef CSTree QElemType; /* 定義佇列元素類型 */
#include"c3-2.h" /* 定義LinkQueue類型(鏈佇列) */
#include"bo3-2.c" /* LinkQueue類型的基本操作 */
void CreateTree(CSTree *T)
{ /* 構造樹T */
char c20; /* 臨時存放孩子結點(設不超過20個)的值 */
CSTree p,p1;
int i,l;
printf("請輸入根結點(字元型,空格為空): ");
scanf("%c%*c",&c0);
if(c0!=Nil) /* 非空樹 */
*T=(CSTree)malloc(sizeof(CSNode)); /* 建立根結點 */
(*T)->data=c0;
(*T)->nextsibling=NULL;
EnQueue(&q,*T); /* 入隊根結點的指針 */
DeQueue(&q,&p); /* 出隊一個結點的指標 */
printf("請按長幼順序輸入結點%c的所有孩子: ",p->data);
gets(c);
l=strlen(c);
if(l>0) /* 有孩子 */
p1=p->firstchild=(CSTree)malloc(sizeof(CSNode)); /* 建立長子結點 */
p1->data=c0;
for(i=1;inextsibling=(CSTree)malloc(sizeof(CSNode)); /* 建立下一個兄弟結點 */
EnQueue(&q,p1); /* 入隊上一個結點 */
p1=p1->nextsibling;
p1->data=ci;
p1->nextsibling=NULL;
EnQueue(&q,p1); /* 入隊最後一個結點 */
p->firstchild=NULL; /* 長子指針為空 */
*T=NULL; /* 空樹 */
Status TreeEmpty(CSTree T)
{ /* 初始條件：樹T存在。操作結果：若T為空樹，則返回TURE，否則返回FALSE */
int TreeDepth(CSTree T)
{ /* 初始條件：樹T存在。操作結果：返回T的深度 */
CSTree p;
int depth,max=0;
if(!T) /* 樹空 */
if(!T->firstchild) /* 樹無長子 */
for(p=T->firstchild;p;p=p->nextsibling)
{ /* 求子樹深度的最大值 */
depth=TreeDepth(p);
if(depth>max)
max=depth;
return max+1; /* 樹的深度=子樹深度最大值+1 */
TElemType Value(CSTree p)
{ /* 返回p所指結點的值 */
TElemType Root(CSTree T)
{ /* 初始條件：樹T存在。操作結果：返回T的根 */
return Value(T);
CSTree Point(CSTree T,TElemType s)
{ /* 返回二叉鏈表(孩子—兄弟)樹T中指向元素值為s的結點的指標。另加 */
DeQueue(&q,&a); /* 出隊,佇列元素賦給a */
if(a->firstchild) /* 有長子 */
EnQueue(&q,a->firstchild); /* 入隊長子 */
if(a->nextsibling) /* 有下一個兄弟 */
EnQueue(&q,a->nextsibling); /* 入隊下一個兄弟 */
Status Assign(CSTree *T,TElemType cur_e,TElemType value)
{ /* 初始條件：樹T存在，cur_e是樹T中結點的值。操作結果：改cur_e為value */
p=Point(*T,cur_e); /* p為cur_e的指針 */
if(p) /* 找到cur_e */
p->data=value; /* 賦新值 */
return ERROR; /* 樹空或沒找到 */
TElemType Parent(CSTree T,TElemType cur_e)
{ /* 初始條件：樹T存在，cur_e是T中某個結點 */
/* 操作結果：若cur_e是T的非根結點，則返回它的雙親，否則函數值為＂空＂*/
CSTree p,t;
if(T) /* 樹非空 */
if(Value(T)==cur_e) /* 根結點值為cur_e */
DeQueue(&q,&p);
if(p->firstchild) /* p有長子 */
if(p->firstchild->data==cur_e) /* 長子為cur_e */
return Value(p); /* 返回雙親 */
t=p; /* 雙親指針賦給t */
p=p->firstchild; /* p指向長子 */
EnQueue(&q,p); /* 入隊長子 */
while(p->nextsibling) /* 有下一個兄弟 */
p=p->nextsibling; /* p指向下一個兄弟 */
if(Value(p)==cur_e) /* 下一個兄弟為cur_e */
return Value(t); /* 返回雙親 */
EnQueue(&q,p); /* 入隊下一個兄弟 */
return Nil; /* 樹空或沒找到cur_e */
TElemType LeftChild(CSTree T,TElemType cur_e)
/* 操作結果：若cur_e是T的非葉子結點，則返回它的最左孩子，否則返回＂空＂*/
CSTree f;
f=Point(T,cur_e); /* f指向結點cur_e */
if(f&&f->firstchild) /* 找到結點cur_e且結點cur_e有長子 */
return f->firstchild->data;
TElemType RightSibling(CSTree T,TElemType cur_e)
/* 操作結果：若cur_e有右兄弟，則返回它的右兄弟，否則返回＂空＂*/
if(f&&f->nextsibling) /* 找到結點cur_e且結點cur_e有右兄弟 */
return f->nextsibling->data;
return Nil; /* 樹空 */
Status InsertChild(CSTree *T,CSTree p,int i,CSTree c)
{ /* 初始條件：樹T存在，p指向T中某個結點，1≦i≦p所指結點的度+1，非空樹c與T不相交 */
/* 操作結果：插入c為T中p結點的第i棵子樹 */
/* 因為p所指結點的位址不會改變，故p不需是參考類型 */
if(*T) /* T不空 */
if(i==1) /* 插入c為p的長子 */
c->nextsibling=p->firstchild; /* p的原長子現是c的下一個兄弟(c本無兄弟) */
p->firstchild=c;
else /* 找插入點 */
p=p->firstchild; /* 指向p的長子 */
while(p&&i>j)
p=p->nextsibling;
if(j==i) /* 找到插入位置 */
c->nextsibling=p->nextsibling;
p->nextsibling=c;
else /* p原有孩子數小於i-1 */
else /* T空 */
Status DeleteChild(CSTree *T,CSTree p,int i)
{ /* 初始條件：樹T存在，p指向T中某個結點，1≦i≦p所指結點的度 */
/* 操作結果：刪除T中p所指結點的第i棵子樹 */
CSTree b;
if(i==1) /* 刪除長子 */
b=p->firstchild;
p->firstchild=b->nextsibling; /* p的原次子現是長子 */
b->nextsibling=NULL;
DestroyTree(&b);
else /* 刪除非長子 */
if(j==i) /* 找到第i棵子樹 */
b=p->nextsibling;
p->nextsibling=b->nextsibling;
else /* p原有孩子數小於i */
void PostOrderTraverse(CSTree T,void(*Visit)(TElemType))
{ /* 後根遍歷孩子—兄弟二叉鏈表結構的樹T */
if(T->firstchild) /* 有長子 */
PostOrderTraverse(T->firstchild,Visit); /* 後根遍歷長子子樹 */
p=T->firstchild->nextsibling; /* p指向長子的下一個兄弟 */
PostOrderTraverse(p,Visit); /* 後根遍歷下一個兄弟子樹 */
p=p->nextsibling; /* p指向再下一個兄弟 */
Visit(Value(T)); /* 最後訪問根結點 */
void LevelOrderTraverse(CSTree T,void(*Visit)(TElemType))
{ /* 層序遍歷孩子—兄弟二叉鏈表結構的樹T */
Visit(Value(T)); /* 先訪問根結點 */
EnQueue(&q,T); /* 入隊根結點的指針 */
if(p->firstchild) /* 有長子 */
p=p->firstchild;
Visit(Value(p)); /* 訪問長子結點 */
EnQueue(&q,p); /* 入隊長子結點的指針 */
Visit(Value(p)); /* 訪問下一個兄弟 */
EnQueue(&q,p); /* 入隊兄弟結點的指針 */
線索二叉樹（，保留遍歷時結點在任一序列的前驅和後繼的資訊）：若結點有左子樹，則其lchild域指示其左孩子，否則令lchild域指示其前驅；若結點有右子樹，則其rchild域指示其右孩子，否則令rchild指示其後繼。還需在結點結構中增加兩個標誌域LTag和RTag。LTag=0時，lchild域指示結點的左孩子，LTag=1時，lchild域指示結點的前驅；RTag=0時，rchild域指示結點的右孩子，RTag=1時，rchild域指示結點的後繼。以這種結點結構構成的二叉鏈表作為二叉樹的存儲結構，叫做線索鏈表，其中指向結點前驅和後繼的指標叫做線索，加上線索的二叉樹稱為線索二叉樹。對二叉樹以某種次序遍歷使其變為線索二叉樹的過程叫做線索化。若對二叉樹進行中序遍歷，則所得的線索二叉樹稱為中序線索二叉樹，線索鏈表稱為為中序線索鏈表。線索二叉樹是一種物理結構。
File:tbt1.jpg
在中序線索樹找結點後繼的規律是：若其右標誌為1，則右鏈為線索，指示其後繼，否則遍歷其右子樹時訪問的第一個結點（右子樹最左下的結點）為其後繼；找結點前驅的規律是：若其左標誌為1，則左鏈為線索，指示其前驅，否則遍歷左子樹時最後訪問的一個結點（左子樹中最右下的結點）為其前驅。
在後序線索樹中找到結點的後繼分三種情況：
#若結點是二叉樹的根，則其後繼為空；
#若結點是其雙親的右孩子，或是其雙親的左孩子且其雙親沒有右子樹，則其後繼即為雙親結點；
#若結點是其雙親的左孩子，且其雙親有右子樹，則其後繼為雙親右子樹上按後序遍歷列出的第一個結點。
二叉樹的二叉線索存儲表示：在線索鏈表上添加一個頭結點，並令其lchild域的指標指向二叉樹的根結點，其rchild域的指標指向中序遍歷時訪問的最後一個結點。令二叉樹中序序列中的第一個結點的lchild域指標和最後一個結點的rchild域的指標均指向頭結點，這樣就建立了一個雙向線索鏈表。二叉樹常採用二叉鏈表方式存儲。
/* 二叉樹的二叉線索存儲表示 */
typedef enum{Link,Thread}PointerTag; /* Link(0)：指針，Thread(1)：線索 */
typedef struct BiThrNode
struct BiThrNode *lchild,*rchild; /* 左右孩子指針 */
PointerTag LTag,RTag; /* 左右標誌 */
}BiThrNode,*BiThrTree;
/* 二叉樹的二叉線索存儲的基本操作 */
void CreateBiThrTree(BiThrTree *T)
{ /* 按先序輸入線索二叉樹中結點的值，構造線索二叉樹T。0(整型)/空格(字元型)表示空結點 */
if(ch==Nil)
*T=(BiThrTree)malloc(sizeof(BiThrNode)); /* 生成根結點(先序) */
(*T)->data=ch; /* 給根結點賦植 */
CreateBiThrTree(&(*T)->lchild); /* 遞迴構造左子樹 */
(*T)->LTag=Link; /* 給左標誌賦值(指標) */
CreateBiThrTree(&(*T)->rchild); /* 遞迴構造右子樹 */
(*T)->RTag=Link; /* 給右標誌賦值(指標) */
BiThrTree pre; /* 全域變數，始終指向剛剛訪問過的結點 */
void InThreading(BiThrTree p)
{ /* 通過中序遍歷進行中序線索化，線索化之後pre指向最後一個結點。演算法6.7 */
if(p) /* 線索二叉樹不空 */
InThreading(p->lchild); /* 遞迴左子樹線索化 */
if(!p->lchild) /* 沒有左孩子 */
p->LTag=Thread; /* 左標誌為線索(前驅) */
p->lchild=pre; /* 左孩子指標指向前驅 */
if(pre && !pre->rchild) /* 前驅不爲空并且前驅沒有右孩子 */
pre->RTag=Thread; /* 前驅的右標誌為線索(後繼) */
pre->rchild=p; /* 前驅右孩子指標指向其後繼(當前結點p) */
pre=p; /* 保持pre指向p的前驅 */
InThreading(p->rchild); /* 遞迴右子樹線索化 */
void InOrderThreading(BiThrTree *Thrt,BiThrTree T)
{ /* 中序遍歷二叉樹T，並將其中序線索化，Thrt指向頭結點。演算法6.6 */
*Thrt=(BiThrTree)malloc(sizeof(BiThrNode));
if(!*Thrt) /* 生成頭結點不成功 */
(*Thrt)->LTag=Link; /* 建頭結點，左標誌為指標 */
(*Thrt)->RTag=Thread; /* 右標誌為線索 */
(*Thrt)->rchild=*Thrt; /* 右指針回指 */
if(!T) /* 若二叉樹空，則左指針回指 */
(*Thrt)->lchild=*Thrt;
(*Thrt)->lchild=T; /* 頭結點的左指標指向根結點 */
pre=*Thrt; /* pre(前驅)的初值指向頭結點 */
InThreading(T); /* 中序遍歷進行中序線索化，pre指向中序遍歷的最後一個結點 */
pre->rchild=*Thrt; /* 最後一個結點的右指標指向頭結點 */
pre->RTag=Thread; /* 最後一個結點的右標誌為線索 */
(*Thrt)->rchild=pre; /* 頭結點的右指標指向中序遍歷的最後一個結點 */
void InOrderTraverse_Thr(BiThrTree T,void(*Visit)(TElemType))
{ /* 中序遍歷線索二叉樹T(頭結點)的非遞迴演算法。演算法6.5 */
BiThrTree p;
p=T->lchild; /* p指向根結點 */
while(p!=T)
{ /* 空樹或遍歷結束時，p==T */
while(p->LTag==Link) /* 由根結點一直找到二叉樹的最左結點 */
p=p->lchild;
Visit(p->data); /* 訪問此結點 */
while(p->RTag==Thread&&p->rchild!=T) /* p->rchild是線索(後繼)，且不是遍歷的最後一個結點 */
p=p->rchild;
Visit(p->data); /* 訪問後繼結點 */
p=p->rchild; /* 若p->rchild不是線索(是右孩子)，p指向右孩子，返回迴圈，*/
}              /* 找這棵子樹中序遍歷的第1個結點 */
void PreThreading(BiThrTree p)
{ /* PreOrderThreading調用的遞迴函數 */
if(!pre->rchild) /* p的前驅沒有右孩子 */
pre->rchild=p; /* p前驅的後繼指向p */
pre->RTag=Thread; /* pre的右孩子為線索 */
if(!p->lchild) /* p沒有左孩子 */
p->LTag=Thread; /* p的左孩子為線索 */
p->lchild=pre; /* p的左孩子指向前驅 */
pre=p; /* 移動前驅 */
if(p->LTag==Link) /* p有左孩子 */
PreThreading(p->lchild); /* 對p的左孩子遞迴呼叫preThreading */
if(p->RTag==Link) /* p有右孩子 */
PreThreading(p->rchild); /* 對p的右孩子遞迴呼叫preThreading */
void PreOrderThreading(BiThrTree *Thrt,BiThrTree T)
{ /* 先序線索化二叉樹T，頭結點的右指標指向先序遍歷的最後1個結點 */
if(!*Thrt) /* 生成頭結點 */
(*Thrt)->LTag=Link; /* 頭結點的左指針為孩子 */
(*Thrt)->RTag=Thread; /* 頭結點的右指針為線索 */
(*Thrt)->rchild=*Thrt; /* 頭結點的右指標指向自身 */
if(!T) /* 空樹 */
(*Thrt)->lchild=*Thrt; /* 頭結點的左指標也指向自身 */
{ /* 非空樹 */
pre=*Thrt; /* 前驅為頭結點 */
PreThreading(T); /* 從頭結點開始先序遞迴線索化 */
pre->rchild=*Thrt; /* 最後一個結點的後繼指向頭結點 */
pre->RTag=Thread;
(*Thrt)->rchild=pre; /* 頭結點的後繼指向最後一個結點 */
void PreOrderTraverse_Thr(BiThrTree T,void(*Visit)(TElemType))
{ /* 先序遍歷線索二叉樹T(頭結點)的非遞迴演算法 */
BiThrTree p=T->lchild; /* p指向根結點 */
while(p!=T) /* p沒指向頭結點(遍歷的最後1個結點的後繼指向頭結點) */
Visit(p->data); /* 訪問根結點 */
p=p->lchild; /* p指向左孩子(後繼) */
else /* p無左孩子 */
p=p->rchild; /* p指向右孩子或後繼 */
void PostThreading(BiThrTree p)
{ /* PostOrderThreading調用的遞迴函數 */
PostThreading(p->lchild); /* 對p的左孩子遞迴呼叫PostThreading */
PostThreading(p->rchild); /* 對p的右孩子遞迴呼叫PostThreading */
pre->RTag=Thread; /* p前驅的右孩子為線索 */
void PostOrderThreading(BiThrTree *Thrt,BiThrTree T)
{ /* 後序遞迴線索化二叉樹 */
(*Thrt)->lchild=(*Thrt)->rchild=*Thrt; /* 頭結點的左右指標指向自身 */
(*Thrt)->lchild=(*Thrt)->rchild=T; /* 頭結點的左右指標指向根結點(最後一個結點) */
PostThreading(T); /* 從頭結點開始後序遞迴線索化 */
if(pre->RTag!=Link) /* 最後一個結點沒有右孩子 */
void DestroyBiTree(BiThrTree *T)
{ /* DestroyBiThrTree調用的遞迴函數，T指向根結點 */
if((*T)->LTag==0) /* 有左孩子 */
if((*T)->RTag==0) /* 有右孩子 */
T=NULL; /* 空指針賦0 */
void DestroyBiThrTree(BiThrTree *Thrt)
{ /* 初始條件：線索二叉樹Thrt存在。操作結果：銷毀線索二叉樹Thrt */
if(*Thrt) /* 頭結點存在 */
if((*Thrt)->lchild) /* 根結點存在 */
DestroyBiTree(&(*Thrt)->lchild); /* 遞迴銷毀頭結點lchild所指二叉樹 */
free(*Thrt); /* 釋放頭結點 */
*Thrt=NULL; /* 線索二叉樹Thrt指針賦0 */
*  binary trees entry in the  FindStat數據庫
*  Gamedev.net introduction on binary trees
*  Balanced binary search tree on array How to create bottom-up an Ahnentafel list, or a balanced binary search tree on array
*  Binary trees and Implementation of the same with working code examples
德語，是印歐語系西日耳曼語支的一門語言。以將其作為官方語言的國家數量計，是世界第六大語言。德語是世界大國語言之一，並且是歐盟內使用最廣的母語。當下，以德語為母語者，有9000萬到9800萬之眾。德語標準共同語的形成可以追溯到馬丁·路德對拉丁文《武加大圣經》的翻譯工作。大多數德語詞匯源于其日耳曼語族的祖先語言（由原始日耳曼語發展而來的古高地德語、中古高地德語、古法蘭克語等），一些詞匯來自拉丁語及古希臘語，還有部分來自法語和英語。
以德語為母語者現在主要分布在德國、奧地利、瑞士東部、列支敦士登和盧森堡。在一些歷史上曾屬泛德意志的地區（如一戰前屬奧地利的意大利南蒂羅爾、一戰前屬普魯士的東比利時、一戰前屬普魯士的丹麥南日德蘭／北什勒斯維希、一戰前屬普魯士的波蘭西里西亞、在德法間數度易手的法國阿爾薩斯和洛林、原德國殖民地納米比亞）目前仍居有眾多以德語為母語的德意志人，是為當地的少數民族。
德語書寫使用拉丁字母。德文字母在26個常規拉丁字母之外，另有三個帶分音符的元音以及一個特殊字母。
德語是一門難學的語言，例如名詞分為陰(die)、中(das)、陽(der)三性，且毫無規律。另外，德語四格變位亦是難點之一。
中世紀初期德語這個詞首次出現。其詞根來源于日耳曼語中的''人民''（''thioda'', 形容詞 ''thiodisk''）一詞，意思是這是一種被大眾使用的語言。當時法蘭克人的高級階層一般使用「法蘭克式的拉丁語」，后來稱為法語。德語當時并不是一種統一的語言，它是許多地方方言的總稱。
中世紀德意志境內諸侯割據，加上交通不便，各個德語方言的發展相差很大。雖然曾試圖建立共同語言，但一般都只局限于各地區，而且只在一定的階層中被利用。比如北德的低地德語在漢薩同盟最興盛的時候在北海和波羅的海沿海地帶成為當地經商的通用語言。
16世紀，馬丁·路德為了推動德意志宗教改革，將《圣經》翻譯成德語的一種方言，為德語的統一起了非常大的作用。《路德圣經》所使用的德語方言，得到了非常廣泛的普及，成為后來標準德語的基礎。
1781年約翰·克里斯托弗·阿德隆出版了第一部德語字典。1852年起雅各布·格林和威廉·格林兄弟開始編輯最廣泛的德語字典。這部著作一直到1960年才完工。1880年康拉德·杜登出版了德語全正體書寫字典。1901年經過小修改后，這部字典成為標準德語的唯一典範。其中的內容一直到1998年才被重新訂正，以配合具爭議性1996年德語正寫法改革。在過渡期內，新拼法在大部份學校裡教授，但媒體則出現新舊拼法混合並行的情況。德國聯邦憲法法院指出各州仍可自行決定是否採用新正寫法，而且只在學校中具有強制性。這意味著人們在學校以外的領域，仍可使用舊有正寫法。2007年，在德國國會沒有干預的情況下，又對正寫法作了一次重大檢討。2007年，一些舊拼法最終失效。新正寫法最明顯的影響是詞語結尾的-ss，如dass及muss成為可接受的拼法。這種拼法在傳統正寫法中是不允許的，一定要寫成da?及mu?。
歐盟國家中的德語使用分佈圖。其中黑色部分是以德語為官方語言的國家或地區
在以下國家德語是唯一的官方語言：
在以下國家德語是官方語言之一：
* 盧森堡（還有盧森堡語和法語）
* 瑞士（還有法語、意大利語和羅曼什語）
* 比利時（還有法語和荷蘭語）
* 意大利的波爾扎諾自治省（還有意大利語、法語和斯洛文尼亞語）
在以下國家德語是少數族裔語言（按使用人數多少排列）：
德語在歐洲占優勢的國家和地區：德國、奧地利、列支敦士登、瑞士的26個州中的19個州、意大利的南蒂羅爾地區、比利時的德語文化區、盧森堡（盧森堡占優勢的語言為盧森堡語，在德國和法國，盧森堡語被認為是德語的方言）。
德語是世界上最常被學習的外語之一（在歐洲常作為第二外語教學）。在日本，醫學的術語是德語，而不是拉丁語。
+ 全球以德語為母語人口大致分佈情形
以德語為母語人口
大部分在亞爾薩斯、洛林兩大區
大部分在波爾扎諾省
德語字母表是由拉丁字母組成，除了拉丁字母的26個字母外德語還有四個字母的變體。
其中 Aa、Ee、Ii、Oo、Uu 以及三個變體字母 ??、??、üü 為元音字母。包括 ? 的其他字母為輔音字母。
由于德語的電腦編碼為西歐語言，國際標準為ISO-8859-1，所以在使用GB系列或BIG5編碼的中文系統（如常見的Windows系列）中用一些純文本無法正確顯示變音字符，必須將德文文字轉換為Unicode編碼才能在文字編輯工具中正常顯示。特別是在使用默認GB2312的瀏覽器查看沒有給出語言編碼的德文網頁時也會出現亂碼。但在中文版的GNU/Linux中由于預設使用UTF-8而避免了亂碼。如果變音字符直接用GB系列或BIG5編碼保存再次打開就會變成亂碼。
德語的發音并不統一。以下主要是在德國使用的標準德語。
德語詞的重音一般在倒數第二個音節上，但不是非常規則，尤其表現在外來詞上。大部分情況下詞幹的音節為重音（如?Spra-che，語言），但有時也有前綴（首碼）（如Aus-spra-che，發音）或后綴（尾碼）（如B?-cke-rei，面包坊）為重音的。假如一個詞是由多個詞合成組成的那么第一個組成部分詞得重音。外來詞的重音一般按該詞在其原語言來標重。得到重音的音節一般發音比較響一些。假如該音節是長音的話，這個音節往往被故意更加拖長一些。
德語的語句有降調，升調和平調。降調一般用在肯定句中。升調一般用在問句中。平調一般用在主句和從句之間。
德語有15個元音（母音）：a?、a、i?、?、o?、?、u?、?、e?、?、??、?、y?、?和??，??沒有對應短音。
德語屬於文法學上所謂“屈折語”，即德語主要靠詞形變化，而不是像孤立語一樣靠語序、虛詞來表達清楚一個句子的含義，如漢語。德文屬于語法較為傳統的語言，它保留了較多來自古代的靜詞的格詞尾變化以及動詞的變位。相對于英語、荷蘭語、瑞典語這些日爾曼兄弟語言而言，德語的語法變化是相當複雜的（冰島語除外）。但和俄語、波蘭語、拉丁語及梵語等非同族語言相比，德語的屈折變化相對來說又是簡單的。馬克·吐溫説過：「聰明人3個月能學會英語、3年學會法語，但要花30年學會德語。」這種説法容或有誇張成份，但也説明德語比一般人認為難學的法語更難學好。
德語名詞分為三個性，四個格，有單複數之分。名詞藉由其本身及修飾、定義它的形容詞、副詞、冠詞之變化來表現它在句子中的位置、功能和意義，稱為變格，而德語的動詞需要根據人稱和時態、語態而變化，稱為動詞變位。其規則比較復雜。
德語名詞的陰陽性無規律，如：
das Auto （汽車，中）
der Bus （公交車，陽）
為何汽車與公交車同屬車，性卻不同？無原因。
德語正寫法即書寫德語的一套指導規則，例如一個單詞的首字母何時大寫，連寫單詞構成新詞時應如何處理其連接處，以及標點符號的規則等。
德國、奧地利、瑞士等德語地區（除盧森堡外）同意自1998年起在學校內使用新德語正寫法。1999年起也適用于德國所有行政機關。
截至2004年，大部份會使用德語的平面媒體如路透社和德新社已經採用了新正寫法。
在德國，經過一段時間的過渡期及對新正寫法作出修訂（如部份舊拼法得到保留，或與新拼法並行）後，自2005年8月1日起，除北萊茵-威斯伐倫和巴伐利亞兩個邦已經正式拒絕使用新正寫法外，在學校裡，舊有拼寫方法會被視為不正確。自2006年起，德國上述兩個邦的公立學校也會強制採用新規則。2004年版的杜登詞典（Duden dictionary）也包括了這些改動。2007年，一些舊拼法最終失效。這意味著新拼寫規則將會由學校開始，廣泛推展到說德語的大眾。
德語是德國和周圍國家使用的一些方言的統稱。
德國方言一般分為低地德語和高地德語兩種。（認為，不宜把低地德語作為德語的一部分。）
現代德語方言分為中部德語和上德語兩部分，標準德語以中部德語為基礎。奧地利和瑞士的方言屬于上德語。德語語言區南部有比較多的方言如奧地利方言、施瓦本方言、巴伐利亞方言、黑森方言、科隆方言、柏林方言等。一般來說越向南方方言的發音越強硬，多短音，多a音。
高地德語，南部德國、奧地利、瑞士的德語方言。“高地”指阿爾卑斯山和臨近的德國南部山區。
值得注意的是，常有人將高地德語與標準德語混為一談，但二者是完全不同的兩個概念。
高地德語對應的德語詞匯是Oberdeutsch，“Ober”一詞意為“高處、上方”，指阿爾卑斯山和臨近的德國南部山區；而標準德語對應的德語詞匯則是Hochdeutsch，其中“hoch”一詞也有“高”的含義但在這里則意為“高貴的、高級的”，而不是指地理概念。
Hochdeutsch一詞在德語中專指標準德語，標準德語發音以德國中部（漢諾威周圍）方言為基礎，德國、奧地利、瑞士使用相同的德語正寫法。
低地德語（通常分為三大體系）：
# 東低地德語，包括柏林、梅克倫堡等地區所使用的東、西普魯士德語都屬于東低地德語。
# 低地薩克森語，例如北美堪薩斯的德裔群體所使用的門諾低地德語（Mennonite Plautdietsch），不來梅、杜塞爾多夫等地使用的北萊因-威斯特法倫州、下薩克森州、石勒蘇益格-荷爾施泰因州絕大多數城市、以及荷蘭東南部很多省的一部分。
# 低地法蘭克語，包括荷蘭語、比利時的佛拉芒語（它與荷蘭語雖然用詞不同，但對應詞的發音相同）、荷蘭的西林堡語等，所以實質上荷蘭語也是一種低地德語，只不過因為政治因素被獨立稱為荷蘭語。一般語言學家認為低地德語是一些獨立的語言，而不是德語的一些方言。低地德語在過去的一個世紀內受到標準德語的沖擊很大。今天在德國北部地區仍廣泛使用低地德語。低地德語保存了日耳曼語族中一些比較原始的成分，它們與荷蘭語和古英語的共同點比同各類高地德語之間更接近。各類低地德語的發音通常比較柔軟，e:音和長音比較多。
一般語言學家認為瑞士德語是德語的一個方言，它與施瓦本方言比較接近。但瑞士德語的發音與標準德語的發音相差懸殊，以至于一般德國人聽不懂。瑞士德語的正體法與標準德語的完全一致，雖然在瑞士也有人利用瑞士德語的發音來書寫，但這種書寫方式不被正式承認。
官僚德語（Beamtendeutsch）是德國機關、法庭等等使用的語言。理論上來說是最標準的德語。但因為官僚德語語句往往非常累贅（從句套從句等等），混有許多機關、法庭用的縮寫和引用法律，公報的條例，加上許多官話中的特用詞（比如火災在官僚德語中不用一般人使用的 Brand 一詞，而用冗長的 Feuerereignis ，失火事故），教育比較低的德國人，或對一個專業不熟悉的人也往往看不懂用官僚德語寫的公報或官方信件。官僚德語常被用來諷刺德國龐大死板的官僚機構。
對德語影響最大的語言是拉丁語。作為中世紀時的學術和高階層語言，今天德語中許多學術概念或表示抽象概念的詞依然來自于拉丁語或希臘語。至今這些詞一般都已被德語化了。
德意志位于歐洲中心，是東西南北的交通要道，也是中世紀諸侯逐鹿之地。德語中含有許多從其他歐洲語言（如法語、波蘭語、意大利語、西班牙語、俄語、希伯來語等等）來的外來詞。許多這些外來詞在其拼寫和發音上都未加改變地被吸收了。
第二次世界大戰后對德語影響最大的外語是英語。英語有時被戲稱為“新標準德語”。據曼海姆的德語研究所2004年初統計，在過去10年中德語中共產生了約700個新詞，其中40%以上直接來自英語或是英語與德語組成的混合詞。英語對德語的沖擊來自下面三個方面：
* 許多新的科技術語直接由英語進入德語詞匯。有些術語雖然也有相應的德語詞，但英語原詞被更廣泛地應用和接受（如 Computer/Rechner，DNA/DNS 等等）。
* 許多跨國公司（甚至德國的跨國公司，如德國西門子公司）內部以英語為工作語言。
雖然德國政府不像法國使用強制措施維護法語那樣來維護德語，但德國社會也已經意識到了德語的英語化問題，也還有很多移民使用英德交雜的錯亂用法。許多有影響的報刊和電視文化節目抨擊這個趨勢，但它們自身也往往無法擺脫和漠視這個趨勢的要求。
德語中也有自己創造的“仿英語”（或稱德製英語）詞匯。最具代表性的是Handy（手機）一詞，英語中handy是個形容詞，意思是“便于使用的”。
英語從德語中借取了很多借詞，而且通常沒有伴隨任何拼寫變化(通常除了消除分音符和取消名詞的首字母大寫)之外:
德語單詞的意思
abseil
用繩索吊下 / 快速游繩(繩降)
ansatz
開端，開始/ 延長部分，套口/ 附加物/ 估計，估價/ 方法，手段
anschluss
連接、端子、接口/ 附加、附加物
自動化/ 自動售貨機、自動裝置
bildungsroman
關注故事主角個人的發展與教育的小說
閃光燈/ 閃電
delicatessen
美味精緻的食物
lit. "double going / living person alive", 面貌極相似的人
dramaturge
professional position within a theatre or opera company that deals mainly with research and development of plays or operas
or  (Swiss spelling)
edelweiss
lit. "replacement", typically used to refer to an inferior substitute for a desired substance or item
節日、慶典/宴會 、派對
gedankenexperiment
gelandesprung
ski jumping for distance on alpine equipment
gemütlichkeit
溫暖舒適的感覺, 舒適, 天性善良, 親切，和藹
form or shape / creature / scheme; a concept of 'wholeness' (etymologically ''die Gestalt'' is the past participle of ''stellen'' used as an abstract noun,  i.&nbsp;e. the same form as contemporary ''die Gestellte'')
Gesundheit! (Amer.)
健康;健康狀況/ 上帝祝福你! (當有人打噴嚏時)
glockenspiel
鐘琴、打擊樂器
heiligenschein
氣象學. "神聖的光亮" / (日月等的)暈
hinterland
lit. mil. "area behind the front-line": interior / backwoods
弄亂了的, 壞了的，破碎的
katzenjammer
字面意義"貓的悲嘆": 酒后的頭痛， 酗酒、暴飲暴食
字面意義"小孩的庭院"&nbsp;– 托兒所或幼兒園
虛假的，只為了賺錢而產生的“藝術”
藥草, (方言)卷心菜、酸白菜
leitmotif
引導情節發展的主題 (動詞 為"領導、指引"的意思)
to plunder
lit. "taking goods by force" (original meaning "to take away furniture" shifted in German and was borrowed by English both during the Thirty Years War)
字面意思為"敲擊吵鬧惡作劇的鬼"
diplomacy based on practical objectives rather than ideals
背包( →  是"後背"的意思)
在自己汁液發酵的鹽醃切絲包心菜、德國酸菜
lit. "game / play": sales pitch / lengthy speech with the intent to persuade
sprachraum
lit. "place/area/room of a language": area where a certain language is spoken
在...上方、超過、優於
übermensch
超人, "overhuman"
verklemmt (Amer.)
字面意義 "卡住的/受壓縮的": 受抑制的, 內向的，退縮的
waldsterben
字面意義 "森林頂梢枯死", dying floral environment
desire, pleasure, or inclination to travel or walk
weltanschauung
字面意義"世界觀": 意識形態、思想體系
字面意義"神奇兒童": 天才兒童，神童
字面意義“時間的精神”：時代精神；時代潮流
zugzwang
下棋術語. "非走不可的一步"
* Fausto Cercignani, ''The Consonants of German: Synchrony and Diachrony'', Milano, Cisalpino, 1979.
* Michael Clyne, ''The German Language in a Changing Europe'' (1995)
* George O. Curme, ''A Grammar of the German Language'' (1904, 1922) — the most complete and authoritative work in English
* Anthony Fox, ''The Structure of German'' (2005)
* W.B. Lockwood, ''German Today: The Advanced Learner's Guide'' (1987)
* Ruth H. Sanders. ''German: Biography of a Language'' (Oxford University Press; 2010) 240 pages. Combines linguistic, anthropological, and historical perspectives in a "biography" of German in terms of six "signal events" over millennia, including the Battle of Kalkriese, which blocked the spread of Latin-based language north.
*  歌德學院 ：德國政府資助的推廣德語機構。
*  The LEO Online Dictionary ：一個德語入口網站，提供許多轉譯其它語言的字典。
*  wiegehtes.com - Deutsch lernen online
大連（或），舊稱旅大市，別稱鯤城、濱城，舊名達爾尼（；）、帶連、青泥洼。位于中國遼東半島遼寧省南端，東瀕黃海，西臨渤海，是中華人民共和國的5個計劃單列市之一、15個副省級市之一、也是全國14個沿海開放城市之一；也是東北地區國際航運中心、東北地區國際物流中心、區域性金融中心。大連地處黃渤海之濱，與山東半島隔海相望，冬無嚴寒，夏無酷暑，素有“北方明珠”、“浪漫之都”之稱，是中國北方沿海重要的經濟、金融、貿易、港口、工業、旅游城市。2001年大連成為中國第一個被聯合國環境規劃署授予“全球環境500佳”的城市。2003年大連被世界銀行評定為中國基礎建設最佳城市第1位、地方保護主義色彩最低城市第7位、行政機關工作效率及廉潔度第4位、勞動力市場活躍度第5位、法院工作效率第1位、國際化及國際融入度第9位。2005年大連成為中國中央文明辦評選的第一批文明城市。2007年與杭州和成都一起被評為中國最佳旅游城市。2009年大連獲得全球“國際花園城市”最高級別組的第一名。大連是夏季達沃斯世界經濟論壇新領軍者年會的舉辦城市。大連位列2010年度中國城市綜合競爭力第二名（含港澳）。2018與2020年一度被GaWc評為Beta-級的世界城市。
繪于宋代的雪山行旅圖，現藏于大連旅順博物館
目前發現的大連地區年代最早的文化遺址位于長海縣小長山島，距今六千多年。盛行于新石器時代末期的石棚墓在大連分布較為廣泛。
戰國末期，今大連地區屬燕國遼東郡。公元前221年秦統一六國后，置遼東郡，治所在襄平（今遼陽）。漢武帝元封四年（公元前107年）在此地設置沓縣，是大連境內最早的縣級建制。今甘井子區內有牧城驛遺址和營城子漢墓，旅順口區內有牧羊城遺址，表明當時境內經濟較為發達，人口稠密。三國魏晉時期為公孫氏割據政權控制，在魏吳之間搖擺不定，境內多戰亂，后為魏所占。之后，公元405年，高句麗開始統治遼東。
隋唐時期多次對高句麗用兵，隋朝曾三征高句麗，終于在唐總章元年（公元668年）收復此地。當時今大連市區被稱為青泥浦。唐開元元年（公元713年），鴻臚卿崔忻受朝廷之命經旅順北上冊封大祚榮為渤海郡王，返回時在旅順黃金山下鑿井兩眼并刻碑記驗，即為唐鴻臚井（石碑于日俄戰爭時被日軍掠走，現存東京皇居內）。遼朝于境內設扶州（后改復州，州治在今瓦房店市復州城鎮）和蘇州，分別作為安置渤海國扶余城所屬扶州女真部人和南蘇城遷來的女真人之地，為今瓦房店市和金州區之發軔。金朝時將蘇州的來蘇、懷化二縣并為化成縣，隸屬于復州，后升格為金州，金州之名由此誕生。明朝于1372年設金、復、蓋三州，1395年廢除，專行衛制，衛所兼管軍事和民政。
明清時代今市區被當地人稱為“青泥洼”。1622年，后金軍攻佔金州、復州二衛，唯有旅順口仍在明軍總兵官黃龍控制下，直到1633年才被攻陷，黃龍自殺殉國。今旅順黃金山下仍有黃龍墓。清初大連地區因連年戰爭而人稀地荒，故先后隸屬海城和蓋平二縣。康熙雍正年間，實行招民墾殖政策，使得人口漸稠。1653年設復州巡檢司。1680年設金州城守章京，1687年設金州城守尉。
大連市役所舊照
日軍在甲午戰爭中執行旅順大屠殺殘害中國人的素描。
第一次鴉片戰爭后，英國頻繁騷擾大連地區沿海。旅順的英文名亞瑟港（Port Arthur）即是來源于聲稱首個發現此地的英軍將領名字，而海圖則根據當地名稱將大連灣標為「DALIANWAN」。
洋務運動時期，清政府在旅順建設號稱東亞第一軍港的海軍基地，并在大連灣修建大量炮臺。李鴻章在修建炮臺的相關奏折中提到“大連灣”，是為此名首次出現于官方文件中。同時又移熊岳副都統衙門于金州，使金州成為遼南要地。
1894年11月21日，中日甲午戰爭中的日軍攻陷旅順，進行了“旅順大屠殺”，對市內居民連續四天進行殺戮，超過二萬人遇害，屠殺過后全市僅剩三十六人被留下埋葬居民尸體，遇難者葬于白玉山東麓的安葬崗，今稱“萬忠墓”。1895年，甲午戰爭中方戰敗，與日方簽訂馬關條約，其中包括割讓遼東半島于日本。日后聞一多曾為旅大作《七子之歌》。
1898年－1905年，在俄、德、法三國干涉（三國干涉還遼）下，日本撤離。隨后沙俄租借大連灣與旅順口，設達爾尼市，并仿照巴黎市區規劃欲將達爾尼建成一座商業城市。旅順建設成亞瑟港海軍基地。
1905年，俄國在日俄戰爭戰敗。根據《樸茨茅斯和約》，俄國撤離遼東半島，日本占領達爾尼和旅順，并改達爾尼為大連，并在石河以南建立關東州廳。俄國人實際建設大連勝利橋以北地區，而大連更多的街道和建筑是日本占領后參照俄國的規劃圖和日本的后續規劃進行建設的。今天大連街道隨處可見的西洋古典、折衷主義風格的建筑以及和式建筑大都是在這一時期所建。日本占領時期，大連城市人口最高時達70余萬，其中中國人近50萬，日本人、朝鮮人20余萬。街道劃分、建筑風格有明顯的殖民色彩：友好廣場以東為歐洲人區，中國人區限制在小崗子一帶。日據時期，大連基本形成現有的城市格局和工業基礎。
1945年8月10日，蘇聯正式向日本宣戰，蘇聯紅軍進攻偽滿洲國，進入并占領包括大連在內的東北地區。8月24日（一說8月22日），蘇軍攻占大連。第二次世界大戰後，同盟國根據《雅爾塔協定》、《中蘇友好同盟條約》，蘇聯軍繼續在今大連市南部包括主城區在內的地區設有駐軍，並在旅順口，依托原有的旅順軍港建立海軍基地。蘇軍占領區，實際上由中共和蘇軍共管長達10年。
1945年10月，中共中央東北局任命韓光為中共大連市委書記，11月8日，成立大連市政府，25日成立旅順市政府。12月，為阻止國民政府接受大連，以大連市郊區設立大連縣。1947年6月，國民政府公布《東北新省區方案》，設立直轄市——大連市，但從未實際管轄。
中華民國設置的大連市
原大連大和旅館舊址，現大連賓館大樓
1949年4月，旅大行署區成立。1950年4月，大連縣并入大連市。10月5日，旅大行署區改為東北大行政區代管的旅大直轄市。1951年，旅順市和大連市兩市之上，設立旅大市。這也是中國大陸第一個市下設市的案例，類似于現今的地級市和縣級市的關系。
1954年6月19日，旅大市由中央直轄市改為遼寧省轄市。1955年，蘇軍撤離大連，蘇聯將大連及旅順的駐軍、防務等主權歸還中華人民共和國。1960年，旅順市劃為旅順口區，仍屬旅大市。
1981年2月，旅大市更名為大連市。1984年，國務院批準大連為沿海開放城市。1984年7月，大連市被國務院確定為計劃單列市，享有省級經濟方面管轄權限。
1994年5月，大連市由普通地級市升為副省級地級市，其轄區不變。
2010年7月16日，大連新港油輪發生輸油管道爆炸事件。
2011年8月14日，發生大連PX事件。同年9月大連成功舉辦世界經濟論壇。
第二次鴉片戰爭中，大連于1858年被英國占領，1860年歸還。1897年年底，沙俄為爭奪清朝領土，將軍艦強行開進旅順口，隨后派人到大連灣和青泥洼勘察，并決定在青泥洼地區開港建市。1899年8月11日，沙皇尼古拉二世發布建立自由港的敕令，并將青泥洼改名為“達爾尼”（，遠方的意思）。1905年，日本在日俄戰爭中戰勝沙俄后，將“達爾尼”改名為“大連”，音譯俄文中的“達爾尼”諧音。
1898年英國出版的中國華北地圖，其中大連灣被標注為“Ta-lien-wan Hr.”
+ 大連地名變遷
遝（縣）轄遝渚
東遝（縣）轄遝渚
青泥洼、大連灣、沙河口
達爾尼（港）
關東（州）轄旅順（市）
關東（州）轄大連（市）
第二次國共內戰
大連市、大連縣
中華人民共和國1950年－1981年
中華人民共和國1981年－
+ 大連新舊地名對照
大連市人民政府
中東鐵路輪船公司
今常高等小學
青泥窪橋小學
中山區中心小學
大連音樂學校
大連理工大學市內校區
大連盲啞學校
大連鐵路分局
南滿鐵道株式會社
大連中央郵局
第二十四中學
第四十八中學
大連市第二十高級中學
彌生高等女學校
大連昭和高等女子學校
第七十一中學
大連兒童保健所
滿鐵大連病院
醫大第一附屬醫院
滿鐵高級職員別墅區
三越株式會社大連支店
天津街百貨商店
大連煤氣公司
大連瓦斯株式會社
大連鐵道工廠
五金交電商店
盛道玻璃製品廠
南滿硝子株式會社
大連電業株式會社
白俄總督公館
大連人民體育場
大連市在中國的位置
大連市地處歐亞大陸東岸，中國遼東半島最南端，位于東經120度58分至123度31、北緯38度43分至40度10分之間，東瀕黃海，西臨渤海，南與山東半島隔海相望，北依遼河平原。是華北、華東的海上門戶，是重要的港口、貿易、工業、旅游城市。
大連依山傍海，城市依山而建。全市總面積12574平方公里，其中老市區面積2415平方公里。地區屬沿海低山丘陵區，全市分為山地、丘陵、海巖階地和島嶼4個基本類型。區內山地丘陵多，平原低地少，整個地形為北高南低，北寬南窄；地勢由中央軸部向東南和西北兩側的黃、渤海傾斜，面向黃海一側長而緩。長白山系千山山脈余脈縱貫本區，絕大部分為山地及久經剝蝕而成的低緩丘陵，平原低地僅零星分布在河流入海處及一些山間谷地；巖溶地形隨處可見，喀斯特地貌和海蝕地貌比較發育。