給出的一些常見的數據結構與算法的筆試面試題,特整理如下,后期遇到新的再更新。
筆試面試題
常見時空復雜度有
- 常數級復雜度:O(1)
- 對數級復雜度:O(logN)
- 線性級復雜度:O(N)
- 線性對數級復雜度:O(NlogN)
- 平方級復雜度:O(N2)
冒泡排序算法(重點)
(1)算法流程
a.比較兩個相鄰的元素,如果第一個比第二個大,則交換兩個元素的位置;
b.對每一對相鄰的元素做同樣的工作,從開始的第一對一致到結尾的最后一對,經過這一步,最后的元素將是最大值;
c.針對所有的元素重復以上步驟,除了最后一個;
d.持續對越來越少的元素重復以上步驟,直到沒有元素需要交換為止;
(2)算法評價(N代表元素個數)
評價時間復雜度O(N^2),比較穩定的排序方法,對樣本的有序性敏感
插入排序算法
(1)算法流程
a.從第一個元素起,該元素可以認為已經有序
b.從下一個元素起依次取出,讓取出的元素依次與左邊的有序數列進行比較
c.如果左邊的元素大於取出的元素,則左邊的元素右移
d.如果左邊的元素小於等於取出的元素,則將取出的元素插入到左邊元素的右邊,或者左邊不再有元素,則將取出的元素插入到最左邊;
e.重復以上過程,直到處理完畢所有的元素為止
(2)算法評價
平均時間復雜度O(N^2),比較穩定的排序方法,對樣本的有序性非常敏感,但是插入排序算法的賦值次數比冒泡少,因此一般情況下略優於冒泡排序
選擇排序
(1)算法流程
a.從第一個元素起依次取出,並且假定取出的元素為最小值,使用min記錄該元素的下標
b.使用min記錄的元素和后續的元素依次進行比較,如果后續元素中有比min記錄的元素還小的元素,則重新記錄該元素的下標到min中,也就是后續記錄變成了min記錄的最小值
c.直到min記錄的最小值和后續所有的元素比較完畢,交換min記錄的最小值和最開始假定的元素之間的位置,此時最小值被移動到了最左邊
d.重復以上過程,直到處理完畢所有元素
(2)算法評價
平均時間復雜度O(N^2),不穩定,對樣本的有序性不敏感,雖然該算法比較的次數多,但是交換的次數少,因此一般情況下也是略優於冒泡排序
例如 30 20 30 50 40,用選擇排序會更改兩個30的前后順序,所以不穩定
快速排序算法
(1)算法流程
a.從樣本數列中選擇中間元素作為基准值,單獨保存起來;
b.重組樣本數列,將所有小於基准值的元素放在基准值的左邊,將所有大於基准值的元素放在基准值的右邊,這個過程叫做分組
c.以遞歸的方式分別對小於基准值的分組和大於基准值的分組進行再次分組,直到處理完畢所有的元素為止
(2)算法評價
平均時間復雜度O(NlogN),不穩定,如果每次都能做到均勻分組,則排序速度最快

選擇、冒泡、快速、插入、希爾、歸並、堆排等。
1.快排:是冒泡排序的一種改進。
優點:快,數據移動少
缺點:穩定性不足
2.歸並:分治法排序,穩定的排序算法,一般用於對總體無序,但局部有序的數列。
優點:效率高O(n),穩定
缺點:比較占用內存
希爾排序
void sort(int *array,int len){
int tmp,i,j,gap;
gap = len ;
do
{
gap = gap / 3 + 1;
for(i=0+gap;i<len;i++){
if(array[i]<array[i-gap]){
tmp = array[i];
for(j=i-gap;j>=0;j=j-gap)
if(array[j]>tmp)
array[j+gap]=array[j];
else
break;
array[j+gap]=tmp;
}
}
}while(gap > 1);
}
堆排序
static void heapAdjust(int * array,int start,int end);
void sort(int *array,int len){
int i,j;
for(i=len/2;i>=0;i--)
heapAdjust(array,i,len-1);
for(i=len-1;i>0;i--){
int tmp=array[i];
array[i]=array[0];
array[0]=tmp;
heapAdjust(array,0,i-1);
}
}
static void heapAdjust(int * array,int start,int end){
int i;
int tmp = array[start];
for(i=2*start+1;i<=end;i=2*i+1){
if(array[i]<array[i+1]&& i<end)
i++;
if(tmp > array[i])
break;
array[start]=array[i];
start = i;
}
array[start]=tmp;
}
插排、冒泡、快排
//編程實現各種排序算法
#include <stdio.h>
//實現冒泡排序算法
void bubble(int arr[],int len)
{
int i = 0,j = 0;
//使用外層循環來控制比較的輪數
for(i = 1; i < len; i++)
{
//使用內層循環控制針對當前輪比較的元素下標
int flag = 1;
for(j = 0; j < len-i; j++)
{
//如果第一個元素大於第二個元素,則交換
if(arr[j] > arr[j+1])
{
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
//表明有數據元素發生了交換
flag = 0;
}
}
//表示剛才的一輪掃描中沒有發生交換
if(1 == flag)
{
// 省略剩余的輪數
break;
}
}
}
//實現插入排序算法
void insert(int arr[],int len)
{
int i = 0,j = 0;
//從第二個元素起,依次取出每個元素
for(i = 1; i < len; i++)
{
//使用臨時變量記錄取出的當前元素值
int temp = arr[i];
//使用取出的元素與左邊的有序數列依次比較,如果左邊的元素大,則左邊元素右移;
for(j = i; arr[j-1] > temp && j >= 1; j--)
{
arr[j] = arr[j-1];
}
//直到左邊元素不再大於取出元素時,插入取出元素
if(j != i)
{
arr[j] = temp;
}
}
}
//實現選擇排序算法
void choose(int arr[],int len)
{
int i = 0,j = 0;
//從第一個元素起依次取出,使用min記錄下標
for(i = 0; i < len-1; i++)
{
int min = i;
//使用取出的元素與后續元素依次比較,如果找到比min記錄元素還小的元素,則重新記錄下標
for(j = i+1; j < len; j++)
{
if(arr[j] < arr[min])
{
min = j;
}
}
//直到min記錄的元素與后續所有元素比較完畢,交換min記錄的元素和最開始取出的元素
if(min != i)
{
int temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
}
}
//實現快速排序
void quick(int arr[],int left,int right)
{
//1.尋找中間元素作為基准值,單獨保存
int p = (left + right)/2;
int pivot = arr[p];
//2.分別使用左邊元素和右邊元素與基准值進行比較,將小於基准值的元素放在左邊,將大於等於基准值的元素放在右邊;
int i = 0,j = 0;
for(i = left,j = right; i < j; )
{
//如果左邊元素存在並且小於基准值時
while(arr[i] < pivot && i < p)
{
i++;
}
//如果左邊元素存在,但是大於等於基准值
if(i < p)
{
arr[p] = arr[i];
p = i;
}
//接下來處理右邊的元素
while(pivot <= arr[j] && p < j)
{
j--;
}
if(p < j)
{
arr[p] = arr[j];
p = j;
}
}
//3.將基准值放在重合的位置上
arr[p] = pivot;
//4.分別對左邊分組和右邊分組重復以上過程,使用遞歸處理
if(p-left > 1)
{
quick(arr,left,p-1);
}
if(right-p > 1)
{
quick(arr,p+1,right);
}
}
int main(void)
{
int arr[9] = {20,5,30,10,15,6,25,12,28};
//使用排序算法進行排序
//bubble(arr,9);
//insert(arr,9);
//choose(arr,9);
quick(arr,0,8);
printf("排序后的結果是:");
int i = 0;
for(i = 0; i < 9; i++)
{
printf("%d ",arr[i]);
}
printf("\n");
return 0;
}
鏈表
//編程實現單鏈表的各種操作
#include <stdio.h>
#include <stdlib.h>
//定義節點的數據類型
typedef struct Node
{
int data;//記錄數據元素本身
struct Node* next;//記錄下一個節點的地址
}Node;
//定義單鏈表的數據類型
typedef struct
{
Node* head;//記錄頭節點的地址
Node* tail;//記錄尾節點的地址
int cnt;//記錄元素的個數
}List;
//判斷鏈表是否為空 empty
int empty(List* pl);
//判斷鏈表是否為滿 full
int full(List* pl);
//計算鏈表中節點個數 size
int size(List* pl);
//向頭節點位置插入新元素的功能 push_head
void push_head(List* pl,int data);
//遍歷鏈表中的所有節點元素值 travel
void travel(List* pl);
//編寫創建新節點的函數 create_node
Node* create_node(int data);
//向鏈表的末尾追加新元素
void push_tail(List* pl,int data);
//向鏈表中任意的下標位置插入新元素
void insert_data(List* pl,int pos,int data);
//實現獲取頭節點的元素值 get_head
int get_head(List* pl);
//實現獲取尾節點的元素值 get_tail
int get_tail(List* pl);
//實現刪除頭節點的功能 pop_head
int pop_head(List* pl);
//刪除尾節點的功能函數
int pop_tail(List* pl);
//刪除指定下標位置的節點
int delete_data(List* pl,int pos);
//逆轉鏈表中所有節點
void reverse_data(List* pl);
//實現逆轉的遞歸函數
void reverse(Node* pn);
//逆序打印鏈表中的所有節點元素
void reverse_travel_data(List* pl);
//實現逆序打印的遞歸函數
void reverse_travel(Node* pn);
//清空鏈表中所有的節點
void clear(List* pl);
int main(void)
{
//單鏈表的創建以及初始化
List list;
list.head = NULL;
list.tail = NULL;
list.cnt = 0;
push_head(&list,11);
travel(&list);// 11
push_head(&list,22);
travel(&list);// 22 11
push_head(&list,33);
travel(&list);// 33 22 11
printf("鏈表中節點元素的個數是:%d\n",size(&list));// 3
printf("%s\n",empty(&list)?"鏈表已經空了":"鏈表不為空");// 鏈表不為空
printf("%s\n",full(&list)?"鏈表已經滿了":"鏈表沒有滿"); // 鏈表沒有滿
printf("--------------------------\n");
push_tail(&list,44);
travel(&list);// 33 22 11 44
push_tail(&list,55);
travel(&list);// 33 22 11 44 55
printf("鏈表中節點元素的個數是:%d\n",size(&list)); // 5
printf("---------------------------\n");
insert_data(&list,-2,66);
travel(&list);//33 22 11 44 55 66
insert_data(&list,0,77);
travel(&list);//77 33 22 11 44 55 66
insert_data(&list,2,88);
travel(&list);//77 33 88 22 11 44 55 66
insert_data(&list,8,99);
travel(&list);//77 33 88 22 11 44 55 66 99
printf("鏈表中節點元素的個數是:%d\n",size(&list)); // 9
printf("--------------------------\n");
printf("頭節點的元素值是:%d\n",get_head(&list));// 77
printf("尾節點的元素值是:%d\n",get_tail(&list));// 99
printf("刪除的頭節點元素是:%d\n",pop_head(&list));// 77
travel(&list);//33 88 22 11 44 55 66 99
printf("頭節點的元素值是:%d\n",get_head(&list));// 33
printf("尾節點的元素值是:%d\n",get_tail(&list));// 99
printf("鏈表中節點元素的個數是:%d\n",size(&list));// 8
printf("--------------------------\n");
travel(&list);//33 88 22 11 44 55 66 99
printf("刪除的尾節點是:%d\n",pop_tail(&list));// 99
printf("鏈表中節點元素的個數是:%d\n",size(&list));// 7
travel(&list);//33 88 22 11 44 55 66
printf("刪除的尾節點是:%d\n",pop_tail(&list));// 66
printf("鏈表中節點元素的個數是:%d\n",size(&list));// 6
travel(&list);//33 88 22 11 44 55
printf("---------------------------\n");
travel(&list);//33 88 22 11 44 55
printf("刪除的節點元素是:%d\n",delete_data(&list,-2)); // -1
travel(&list);//33 88 22 11 44 55
printf("刪除的節點元素是:%d\n",delete_data(&list,0));// 33
travel(&list);// 88 22 11 44 55
printf("刪除的節點元素是:%d\n",delete_data(&list,2));// 11
travel(&list);// 88 22 44 55
printf("刪除的節點元素是:%d\n",delete_data(&list,3));// 55
travel(&list);// 88 22 44
printf("--------------------------\n");
reverse_data(&list);
travel(&list);// 44 22 88
printf("--------------------------\n");
printf("逆序打印的結果是:");
reverse_travel_data(&list);// 88 22 44
printf("正序打印的結果是:");
travel(&list);// 44 22 88
printf("-----------------------\n");
clear(&list);
travel(&list); // 啥也沒有
return 0;
}
//清空鏈表中所有的節點
void clear(List* pl)
{
while(-1 != pop_head(pl));
}
//逆序打印鏈表中的所有節點元素
void reverse_travel_data(List* pl)
{
//1.調用遞歸函數進行打印
reverse_travel(pl->head);
//2.打印換行符增加美觀
printf("\n");
}
//實現逆序打印的遞歸函數
void reverse_travel(Node* pn)
{
if(pn != NULL)
{
//1.打印后續節點元素值,使用遞歸
reverse_travel(pn->next);
//2.打印頭節點元素值
printf("%d ",pn->data);
}
}
//實現逆轉的遞歸函數
void reverse(Node* pn)
{
// 確保鏈表中至少有兩個節點才需要逆轉
if(pn != NULL && pn->next != NULL)
{
//采用遞歸逆轉后續的元素
reverse(pn->next);
//逆轉兩個節點的方法
pn->next->next = pn;
pn->next = NULL;
}
}
//逆轉鏈表中所有節點
void reverse_data(List* pl)
{
//1.調用遞歸函數進行逆轉
reverse(pl->head);
//2.交換head 和 tail的指向
Node* pt = pl->head;
pl->head = pl->tail;
pl->tail = pt;
}
//刪除指定下標位置的節點
int delete_data(List* pl,int pos)
{
//1.判斷下標位置是否合法
if(pos < 0 || pos >= size(pl))
{
printf("下標位置不合法,刪除失敗\n");
return -1;//刪除失敗
}
//2.當 pos = 0時,刪除頭節點
if(0 == pos)
{
return pop_head(pl);
}
//3.當 pos = cnt-1時,刪除尾節點
if(size(pl)-1 == pos)
{
return pop_tail(pl);
}
//4.當 pos為其他值時,刪除中間節點
Node* pt = pl->head;
int i = 0;
for(i = 1; i < pos; i++)
{
pt = pt->next;
}
Node* pm = pt->next;
pt->next = pm->next;
int temp = pm->data;
free(pm);
pm = NULL;
--pl->cnt;
return temp;
}
//刪除尾節點的功能函數
int pop_tail(List* pl)
{
//判斷鏈表是否為空
if(empty(pl))
{
return -1;//刪除失敗
}
//當鏈表中只有一個節點時
if(1 == size(pl))
{
int temp = pl->head->data;
free(pl->head);
pl->head = pl->tail = NULL;
--pl->cnt;
return temp;
}
//當鏈表中有更多的節點時,采用歸納法
//先將相對於cnt=2時多出來的next執行完畢
Node* pt = pl->head;
int i = 0;
for(i = 2; i < size(pl); i++)
{
pt = pt->next;
}
//接下來寫cnt = 2時 的刪除代碼
int temp = pl->tail->data;
free(pl->tail);
pl->tail = pt;
// 為了避免記錄已經刪除節點的地址
pl->tail->next = NULL;
--pl->cnt;
return temp;
}
//實現獲取頭節點的元素值 get_head
int get_head(List* pl)
{
return empty(pl)?-1:pl->head->data;
}
//實現獲取尾節點的元素值 get_tail
int get_tail(List* pl)
{
return empty(pl)?-1:pl->tail->data;
}
//實現刪除頭節點的功能 pop_head
int pop_head(List* pl)
{
if(empty(pl))
{
return -1;//刪除失敗
}
Node* pt = pl->head;
int temp = pt->data;
pl->head = pt->next;
free(pt);
pt = NULL;
//當鏈表中只有一個節點時,tail置為NULL
if(NULL == pl->head)
{
pl->tail = NULL;
}
--pl->cnt;
return temp;
}
//向鏈表中任意的下標位置插入新元素
void insert_data(List* pl,int pos,int data)
{
//1.判斷坐標是否合法
if(pos < 0 || pos > size(pl))
{
//printf("坐標不合法,插入失敗\n");
//return;//結束當前函數
//pos = 0; //默認插入到鏈表的頭節點位置
pos = size(pl);//默認插入到鏈表的尾部
}
//2.將新元素插入指定的位置
if(0 == pos)
{
push_head(pl,data);
return;
}
if(size(pl) == pos)
{
push_tail(pl,data);
return;
}
//接下來就是插入到中間位置的情況
Node* pn = create_node(data);
Node* pt = pl->head;
//使用for循環將相對於pos=1多出來的next走完
int i = 0;
for(i = 1; i < pos; i++)
{
pt = pt->next;
}
//接下來把pos=1時的代碼寫下來即可
pn->next = pt->next;
pt->next = pn;
//讓節點的個數加1
++pl->cnt;
}
//向鏈表的末尾追加新元素
void push_tail(List* pl,int data)
{
//1.創建新節點
Node* pn = create_node(data);
//2.將新節點插入到鏈表的末尾
if(empty(pl))
{
pl->head = pn;
}
else
{
pl->tail->next = pn;
}
pl->tail = pn;
//3.將節點的個數 加1
++pl->cnt;
}
//編寫創建新節點的函數 create_node
Node* create_node(int data)
{
Node* pn = (Node*)malloc(sizeof(Node));
if(NULL == pn)
{
printf("創建節點失敗\n");
//return;
exit(-1);
}
pn->data = data;
pn->next = NULL;
return pn;
}
//判斷鏈表是否為空 empty
int empty(List* pl)
{
return NULL == pl->head;
}
//判斷鏈表是否為滿 full
int full(List* pl)
{
return 0;
}
//計算鏈表中節點個數 size
int size(List* pl)
{
return pl->cnt;
}
//向頭節點位置插入新元素的功能 push_head
void push_head(List* pl,int data)
{
//1.創建新節點,初始化
/*
Node* pn = (Node*)malloc(sizeof(Node));
if(NULL == pn)
{
printf("創建節點失敗\n");
return;
}
pn->data = data;
pn->next = NULL;
*/
Node* pn = create_node(data);
//2.將新節點插入到頭節點的位置
if(empty(pl))
{
pl->head = pl->tail = pn;
}
else
{
pn->next = pl->head;
pl->head = pn;
}
//3.節點元素的個數 加1
++pl->cnt;
}
//遍歷鏈表中的所有節點元素值 travel
void travel(List* pl)
{
printf("鏈表中的元素有:");
Node* pt = pl->head;
while(pt != NULL)
{
printf("%d ",pt->data);
pt = pt->next;
}
printf("\n");
}
有序二叉樹
//編程實現有序二叉樹的各種操作
#include <stdio.h>
#include <stdlib.h>
//定義節點的數據類型
typedef struct Node
{
int data;//記錄數據元素本身
struct Node* left;//記錄左子節點的地址
struct Node* right;//記錄右子節點的地址
}Node;
//定義有序二叉樹的數據類型
typedef struct
{
Node* root;//記錄根節點的地址
int cnt;//記錄節點的個數
}Tree;
//向有序二叉樹中插入元素
void insert_data(Tree* pt,int data);
//實現插入節點的遞歸函數
void insert(Node** pRoot,Node* pn);
//采用中序遍歷方式來遍歷有序二叉樹
void travel_data(Tree* pt);
//遍歷的遞歸函數
void travel(Node* pn);
//判斷有序二叉樹是否為空 empty
int empty(Tree* pt);
//判斷有序二叉樹是否為滿 full
int full(Tree* pt);
//獲取根節點的元素值 get_root
int get_root(Tree* pt);
//獲取有序二叉樹中節點的個數 size
int size(Tree* pt);
//清空有序二叉樹中的所有節點
void clear_data(Tree* pt);
//清空的遞歸函數
void clear(Node** ppn);
//查找指向目標元素指針的地址
Node** find_data(Tree* pt,int data);
//查找的遞歸函數
Node** find(Node** ppn,int data);
//刪除指定的元素
int delete_data(Tree* pt,int data);
//修改指定的元素
void modify_data(Tree* pt,int old_data,int new_data);
int main(void)
{
//創建有序二叉樹,並且進行初始化
Tree tree;
tree.root = NULL;
tree.cnt = 0;
insert_data(&tree,50);
travel_data(&tree);//50
insert_data(&tree,70);
travel_data(&tree);//50 70
insert_data(&tree,20);
travel_data(&tree);//20 50 70
insert_data(&tree,60);
travel_data(&tree);//20 50 60 70
insert_data(&tree,40);
travel_data(&tree);//20 40 50 60 70
printf("--------------------------\n");
printf("%s\n",empty(&tree)?"有序二叉樹已經空了":"有序二叉樹沒有空");//有序二叉樹沒有空
printf("%s\n",full(&tree)?"有序二叉樹已經滿了":"有序二叉樹沒有滿");//有序二叉樹沒有滿
printf("有序二叉樹的根節點元素是:%d\n",get_root(&tree));// 50
printf("有序二叉樹中節點元素的個數是:%d\n",size(&tree));// 5
printf("-------------------------\n");
travel_data(&tree);//20 40 50 60 70
delete_data(&tree,50);
travel_data(&tree);//20 40 60 70
delete_data(&tree,40);
travel_data(&tree);//20 60 70
modify_data(&tree,20,40);
travel_data(&tree);//40 60 70
printf("-------------------------\n");
clear_data(&tree);
travel_data(&tree); // 啥也沒有
return 0;
}
//修改指定的元素
void modify_data(Tree* pt,int old_data,int new_data)
{
//1.刪除舊元素
int res = delete_data(pt,old_data);
if(-1 == res)
{
printf("目標元素不存在,修改失敗\n");
return;
}
//2.插入新元素
insert_data(pt,new_data);
}
//刪除指定的元素
int delete_data(Tree* pt,int data)
{
//查找目標元素所在的地址信息
Node** ppn = find_data(pt,data);
if(NULL == *ppn)
{
return -1;//刪除失敗
}
//將要刪除節點的左子樹合並到右子樹中
if((*ppn)->left != NULL)
{
insert(&(*ppn)->right,(*ppn)->left);
}
//尋找臨時指針記錄要刪除的節點地址
Node* pn = *ppn;
//將指向要刪除節點的指針指向它的右子樹
*ppn = (*ppn)->right;
//釋放要刪除的節點
free(pn);
pn = NULL;
//節點的個數減 1
--pt->cnt;
return 0;//刪除成功
}
//查找指向目標元素指針的地址
Node** find_data(Tree* pt,int data)
{
//調用遞歸函數進行查找
return find(&pt->root,data);
}
//查找的遞歸函數
Node** find(Node** ppn,int data)
{
//如果有序二叉樹為空,查找失敗
if(NULL == *ppn)
{
return ppn;
}
//如果目標元素和根元素相等,則查找成功
else if(data == (*ppn)->data)
{
return ppn;
}
//如果目標元素小於根元素,則查找左子樹
else if(data < (*ppn)->data)
{
return find(&(*ppn)->left,data);
}
//如果目標元素大於根元素,則查找右子樹
else
{
return find(&(*ppn)->right,data);
}
}
//清空的遞歸函數
void clear(Node** ppn)
{
if(*ppn != NULL)
{
//1.清空左子樹
clear(&(*ppn)->left);
//2.清空右子樹
clear(&(*ppn)->right);
//3.釋放根節點
free(*ppn);
*ppn = NULL;
}
}
//清空有序二叉樹中的所有節點
void clear_data(Tree* pt)
{
//調用遞歸函數來釋放所有的節點
clear(&pt->root);
//節點個數 置為0
pt->cnt = 0;
}
//判斷有序二叉樹是否為空 empty
int empty(Tree* pt)
{
return NULL == pt->root;
}
//判斷有序二叉樹是否為滿 full
int full(Tree* pt)
{
return 0;
}
//獲取根節點的元素值 get_root
int get_root(Tree* pt)
{
return empty(pt)?-1:pt->root->data;
}
//獲取有序二叉樹中節點的個數 size
int size(Tree* pt)
{
return pt->cnt;
}
//遍歷的遞歸函數
void travel(Node* pn)
{
if(pn != NULL)
{
//1.遍歷左子樹,使用遞歸
travel(pn->left);
//2.遍歷根節點
printf("%d ",pn->data);
//3.遍歷右子樹,使用遞歸
travel(pn->right);
}
}
//采用中序遍歷方式來遍歷有序二叉樹
void travel_data(Tree* pt)
{
printf("有序二叉樹中的元素有:");
//調用遞歸函數實現遍歷
travel(pt->root);
printf("\n");
}
//實現插入節點的遞歸函數
void insert(Node** pRoot,Node* pn)
{
// Node** pRoot = &pt->root;
// pRoot = &pt->root;
// *pRoot = *(&pt->root) = pt->root;
//1.如果有序二叉樹為空,則直接指向新節點
if(NULL == *pRoot)
{
*pRoot = pn;
return;
}
//2.如果新節點的元素值小於根節點,則插入到左子樹,使用遞歸
else if(pn->data < (*pRoot)->data)
{
insert(&(*pRoot)->left,pn);
}
//3.如果新節點的元素值大於等於根節點,則插入到右子樹中,使用遞歸
else
{
insert(&(*pRoot)->right,pn);
}
}
//向有序二叉樹中插入元素
void insert_data(Tree* pt,int data)
{
//1.創建新節點,並且進行初始化
Node* pn = (Node*)malloc(sizeof(Node));
if(NULL == pn)
{
printf("創建新節點失敗\n");
return;
}
pn->data = data;
pn->left = NULL;
pn->right = NULL;
//2.將新節點插入到合適的位置上,調用遞歸
insert(&pt->root,pn);
//3.節點的個數 加1
++pt->cnt;
}
參考資料
