数据结构算法(C,C++)南邮考研自用

数据结构算法

南邮数据结构自己整理的基础算法,掺杂了南邮的C语言教材和王道教材

章节目录

&2 线性表

&2.1 顺序表

顺序存储类型:

#define MaxSize 50	//线性表最大长度
typedef struct {
    ElemType data[ MaxSize ];	//创建数据元素数组
    int length;	//线性表当前长度
} SqList;	//线性表静态顺序实现sqlist

动态分配线性表:

#define InitSize 100	//线性表最大长度
typedef struct {
    ElemType *data;	//指示动态数组的指针
    int MaxSize;	//数组最大容量
    int length;	//数组当前长度
} SeqList;	//线性表动态顺序实现seqlist

初始化动态分配:

#define error 0
#define ok 1
typedef int Status ;	//类型定义
Status Init ( SeqList *L , int size ) {		//Init初始化函数,status为整型=int
    L -> MaxSize = size;	//线性表最大长度
    L -> length = 0;	//当前长度
    L -> data = ( ElemType *) malloc ( sizeof ( ElemType ) * size );	//动态分配数组空间,malloc动态分配函数
    if ( !L -> data ) {	//动态数组为空执行
        return error;	//0
    }
    return ok;	//1
}

查找(按位查找):

Status Find ( SeqList L , int i , ElemType *x) {	//按位查找函数
	if ( i < 0 || i > L -> length - 1 ) {	//越界判断
		return error;
	}
	*x = L -> data[ i ];	//取出data[i]通过参数x返回
	return ok;
}

查找(按值查找):

int LocateElem ( SeqList L , ElemType e ) {		//按值查找函数
	int i;	//位序
	for ( i = 0 ; i < L -> lentgh ; i++ ) {	//循环查找
		if ( L -> data[ i ] == e ) {	//判断是否相等
			return i + 1;	//返回位序
		}
	}
	return 0;
}

插入(在Ai后面插入x):

Status Insert ( SeqList *L , int i , ElemType x ) {	//插入函数
    int j;	//循环下标
    if ( i < -1 || i > L -> length -1 ) {	//越界判断
        return error;
    }
    if ( L -> length == L -> MaxSize ) {	//数组是否满长
        return error;
    }
    for ( j = L -> length - 1 ; j > i ; j-- ) {	//从后往前依次将数组元素往后移一位
        L->data[ j + 1 ] = L->data[ j ];
    }
    L -> data[ i + 1 ] = x;	//将元素放入后一位位置
    L -> length = L -> length + 1;	//表长长度+1
    return ok;
}

删除(Ai位置删除):

Status Delete ( SeqList *L , int i , ElemType *x ) {	//删除函数
    int j;	//循环下标
    if ( i < 0 || i > L -> length - 1 ) {	//越界判断
        return error;
    }
    if ( !L -> length ) {	//线性表是否为空
        return error;
    }
    e = L -> data[ i ];	//取出data[i]通过参数x返回
    for ( j = length + 1 ; j < L -> length ; j++ ) {	//从后往前依次将数组元素往前移一位
        L -> data[ j - 1 ] = L -> data[ j ];
    }
    L->length --;	//表长长度-1
    return ok;
}

输出(顺序表元素依次输出):

Status Output ( SeqList *L ) {	//输出顺序表元素
    int i;	//循环下标
    if ( L -> length == 0 ) {	//线性表是否为空
        return error;
    }
    for ( i = 0 ; i <= L -> length ; i++ ) {	//从前往后数组依次输出
        printf( "%d " , L -> data[ i ] );
    }
    printf( "\n" );
    return ok;
}

撤销(释放动态分配空间,防止内存泄漏):

void Destory ( SeqList *L ) {
    L -> length = 0;
    L -> MaxSize = 0;
    free( L -> data );
}
&2.2 链式存储
&2.2.1单链表类型定义
typedef struct node {	//单链表结点
    ElemType element;	//结点数据域
    struct node *link;	//结点指针域
} Node;
typedef struct singleList {		//单链表
    Node *first;	//头指针
    int n;		//单链表元素个数
} SingleList;

单链表初始化:

Status Init ( SingleList *L ) {
    L -> first = NULL;	//第一个结点为空结点
    L -> n = 0;		//元素个数为0
    return ok;
}

头插法建立单链表:

SingleList List_HeadInsert ( SingleList &L ) {	//头插法
    Node *s;
    int x;		//数据域
    L = ( SingleList ) malloc ( sizeof ( Node ) );		//创建头结点
    L -> next = NULL;	//指针域为空
    scanf( "%d" , &x );
    while ( x != 9999 ) {		//9999表示结束
        s = ( Node* ) malloc ( sizeof ( Node ) );		//创建新结点
        s -> element = x;		//赋值
        s -> next = L -> next;	//将原来头结点的指针域赋给插入结点
        L -> next = s;			//将插入结点作为头结点的指针域
        scanf( "%d" , &x );
    }
    return L;
}

尾插法建立单链表:

SingleList List_TailInsert ( SingleList &L ) {
    int x;
    L = ( SingleList ) malloc ( sizeof ( Node ) );		//创建头结点
    Node *s;			//插入结点
    Node *r = L;		//表尾指针
    scanf( "%d" , &x );
    while ( x != 9999 ) {		//9999表示结束
        s = ( Node* ) malloc ( sizeof ( Node ) );		//创建新结点
        s -> element = x;		//数据域赋值
        r -> next = s;			//表尾指针结点域赋值
        r = s;			//表尾指针更换
        scanf( "%d" , &x );
    }
    r -> next = NULL;		//表尾指针结点域为NULL
    return L;
}

按序号查找(数据域):

Status Find_Element ( SingleList L , int i , ElemType *x ) {	//链表,位序,值
	Node *p;
    int j;
    if ( i < 0 || i > L-> n - 1 ) {		//越界判断
        return error;
    }
    p = L -> first;		//头结点
    for ( j = 0 ; j < i ; j++ ) {		//遍历到指定位序
        p = p -> link;
    }
    *x = p -> element;		//取出指定结点的元素值
    return ok;
}

按序号查找(结点):

Node *Find_Node ( SingleList L , int i ) {	//链表,位序,值
	Node *p;
    int j;
    if ( i < 0 || i > L-> n - 1 ) {		//越界判断
        return error;
    }
    p = L -> first;		//头结点
    for ( j = 0 ; j < i ; j++ ) {		//遍历到指定位序
        p = p -> link;
    }
    		//取出指定结点的元素值
    return p;
}

按结点值查找:

Node *Locate_Elem ( SingleList L , ElemType e ) {		//链表,值
    Node *p = L -> first;		//头结点
    p = p -> link;		//第一个结点
    while ( p != NULL && p -> element != e ) {		//判断空结点和数据域值
		p = p -> link;
    }
    return p;
}

插入(前插在i位置):

p = Find_Node ( L , i - 1 );	//找到插入位置前一个位置
s -> link = p -> link;			//结点域赋值
p -> link = s;			//结点域赋值

完整插入:

Status Insert ( SingleList *L , int i , ElemType x ) {
    Node *p , *q;
    int j;
    if ( i < -1 || i > L -> n - 1 ) {	//越界判断
        return error;
    }
    p = L -> first;
    for ( j = 0 ; j < i ; j++ ) {		//新结点放后面
        p = p -> link;
    }
    q = ( Node* ) malloc ( sizeof( Node ) );	//生成新结点
    q -> element = x;
    if ( i > -1 ) {
        q -> link = p -> link;		//放入后面结点
        p -> link = q;
    } else {
        q -> link = L -> first;		//变成头结点
        L -> first = q;
    }
    L -> n ++;
    return ok;
}

插入(s插入到p之前):

s -> link = p -> link;		//结点域赋值
p -> link = s;			//交换位置
temp = p -> element;		//交换数据域
p -> element = s -> element;
s -> element = temp;

删除:

p = Find_Node( L , i - 1 );		//找前驱
q = p -> link;		//找到被删除结点
p -> link = q -> link;		//删除结点域赋值给前驱结点的结点域
free( q );		//释放结点

删除(赋值):

q = p -> link;		//找后继结点
p -> element = p -> link -> element;	//后继值赋值
p -> link = q -> link;		//后继的后继为后继
free( q );

完整删除:

Status Delete ( SingleList *L , int i ) {
	int j;
    Node *p, *q;
    if ( !L -> n ) {		//空表判断
        return error;
    }
    if ( i < 0 || i > L -> n - 1 ) {	//月结判断
        return error;
    }
    q = L -> first;
    p = L -> first;
    for ( j = 0 ; j < i - 1 ; j++ ) {
        q = q -> link;
    }
    if ( i == 0 ) {
		L -> first = L -> first -> link;	//头结点为头结点的结点域
    } else {
        p = q -> link;			//后继的后继为后继
        q -> link = p -> link;
    }
    free( q );
    L -> n--;
    return ok;
}

输出:

Status Output( SingleList *L ) {
    Node *p;
    if ( !L -> n ) {		//空表判断
        return error;
    }
    p = L -> first;
    while( p ) {
        printf( "%d" , p -> element );
        p = p -> link;
    }
    return ok;
}

撤销:

void Destory( SingleList *L ) {
    Node *p;
    while ( L -> first ) {
        p = L -> first -> link;		//保存后继
        free( L -> first );
        L -> first = p;
    }
}
&2.2.2带表头结点的单链表
typedef struct headerList {		//同SingleList
    Node *head;
    int n;
} HeaderList;

初始化:

Status Init ( HeaderList *h ) {
	h -> head = ( Node* ) malloc ( sizeof( Node ) );
    if ( ! h -> head ) {
        return error;
    }
    h -> head -> link = NULL;
    h -> n = 0;
    return ok;
}

插入:

Status Insert ( HeaderList *h , int i , ElemType x ) {
    Node *p, *q;
    int j;
    if ( i < - 1 || i > h -> n - 1 ) {
        return error;
    }
    p = h -> head;
    for ( j = 0 ; j <= i ; j++ ) {
        p = p -> link;
    }
    q = ( Node* ) malloc ( sizeof( Node ) );
    q -> element = x;
    q -> link = p -> link;		//后继为插入的后继
    p -> link = q;
    h -> n ++;
    return ok;
}

删除:

Status Delete ( HeaderList * h , int i ) {
    int j;
    Node *p, *q;
    if ( !h -> n ) {
        return error;
    }
    if ( i < 0 || i > h -> n - 1 ) {
        return error;
    }
    q = h -> head;
    for ( j = 0 ; j < i ; j++ ) {
        q = q -> link;
    }
    p = q -> link;
    q -> link = p -> link;		//后继结点替换
    free( p );
    h -> n --;
    return ok;
}
&2.2.3循环单链表
r -> link = L -> head;	//表尾指针的结点域为表头结点
&2.2.4双向链表
typedef struct duNode {
    ElemType element;
    struct duNode *llink;		//左结点
    struct duNode *rlink;		//右结点
} DuNode , Dulist;

插入:

q -> llink = p -> link;		//先把插入的两端赋值
q -> rlink = p;
p -> llink -> rlink = q;	//先赋值前端
p -> link = q;				//最后赋值两个结点关联的结点域

删除:

p -> llink -> rlink = p -> rlink;		//左右结点直接赋值
p -> rlink -> llink = p -> llink;
free( p );
&2.2.5循环双链表
p -> llink = L -> head;			//p为尾结点
L -> head -> llink = L;			//空表
L -> head -> rlink = L;
&2.2.6静态链表
#define MaxSize 50
typedef struct {
    ElemType data;		//存储数据元素
    int next;		//结点域为数组下标
} SLinkList[ MaxSize ];
&2.2.7线性表应用

多项式类型定义:

typedef struct pNode {
    int coef;
    int exp;
    struct pNode* link;
} PNode;
typedef struct polunominal {
    PNode *head;
} Polynominal;

多项式创建:

void Create ( Polynominal *p ) {
    PNode *pn, *pre, *q;	//插入结点,前驱结点,后继结点
    p -> head = ( PNode* ) malloc ( sizeof( PNode ) );
    p -> head -> exp = - 1;
    p -> head -> link = p -> head;
    for ( ; ; ) {
        pn = ( PNode* ) malloc ( sizeof( PNode ) );
        printf( "coef:\n" );
        scanf( "%d" , &pn -> coef );
        printf( "exp:\n" );
        scanf( "%d" , &pn -> exp );
        if ( pn -> exp < 0 ) {
            break;
        }
        pre = p -> head;
        q = p -> head -> link;
        while ( q && q -> exp > pn -> exp ) {	//q为小于pn的结点,pre为大于pn的结点
            pre = q;
            q = q -> link;
        }
        pn -> link = q;
        pre -> link = pn;
    }
}

多项式加法:

void Add ( Polynominal *px , Polynominal *qx ) {
    PNode *q, *q1 = qx -> head , *p, *p1, *temp;
    p = px -> head -> link;				//px第一个结点
    q = q1 -> link;			//q1是q的前驱
    while ( p -> exp >= 0 ) {
        while ( p -> exp < q -> exp ) {		//跳过系数大的项
            q1 = q;
            q = q -> link;
        }
        if ( p -> exp == q -> exp ) {		//指数相等
            q -> coef = q -> coef + p -> coef;
            if ( q -> coef == 0 ) {			//系数和为0则删除结点
                q1 -> link = q -> link;
                free( q );
                q = q1 -> link;
                p = p -> link;
            } else {			//不为0则不管
                q1 = q;
                q = q -> link;
                p = p -> link;
            }
        } else {		//不存在相对应指数项,插入相关项
            temp = ( PNode* ) malloc ( sizeof( PNode ) );
            temp -> coef = p -> coef;
            temp -> exp = p -> exp;
            temp -> link = q1 -> link;
            q1 -> link = temp;
            q1 = q1 -> link;
            p = p -> link;
        }
    }
}

&3 栈和队列

&3.1 栈
&3.1.1 栈顺序结构实现
typedef struct stack {
    int top;	//当前栈顶位置下标,初始为-1,栈长为top+1
    int maxSize;	//maxSize-1为堆栈最大栈顶位置下标
    ElemType *element;		//存储堆栈元素的一维数组首地址指针
    //ElemType data[ maxSize ];
} Stack;
&3.1.2 栈的基本运算

初始化(创建)

void Create ( Stack *s , int mSize ) {
    S -> maxSize = mSize;
    S -> element = ( ElemType * ) malloc ( sizeof ( ElemType ) * mSize );
    S -> top = -1;
}

销毁栈,释放数组空间:

void Destroy ( Stack *S ) {
    S -> maxSize = 0;
    free( S -> element );
    S -> top = -1;
}

判断空栈:

bool IsEmpty ( Stack *S ) {
    return S -> top == -1;
}

判断栈满:

bool IsFull ( Stack *S ) {
    return S -> top == S -> maxSize - 1;
}

获取栈顶元素:

bool Top ( Stack *S , ElemType *x ) {
    if ( IsEmpty ( S ) ) {
        return false;
    }
    *x = S -> element [ S -> top ];
    return true;
}

入栈操作:

bool Push ( Stack *S , ElemType x ) {
    if ( IsFull ( S ) ) {
        return false;
    }
    S -> top ++;
    S -> element [ S -> top ] = x;
    return true;
}

出栈操作:

bool Pop ( Stack *S ) {
    if ( IsEmpty ( S ) ) {
        return false;
    }
    S -> top --;
    return true;
}

清除堆栈中所有元素,不释放空间:

void Clear ( Stack *S ) {
    S -> top = -1;
}
&3.1.3 栈的链式存储

链式存储类型:

typedef struct Linknode {
    ElemType data;
    struct Linknode *next;
} *LiStack;
&3.2 队列
&3.2.1 队列顺序表示
typedef struct queue {
    int front;	//指向队头元素前一个位置
    int rear;	//指向队尾元素
    int maxSize;
    ElemType *element;
} Queue;

队空:

Q -> front == Q -> rear;
&3.2.2 循环队列

循环队列结构体定义:

typedef struct queue {
    int front;
    int rear;
    int maxSize;
    ElemType *element;
} Queue;

创建空队列:

void create( Queue *Q , int mSize ) {
    Q -> maxSize = mSize;
    Q -> element = ( ElemType *) malloc ( sizeof( ElemType) * mSize );
    Q -> front = Q -> rear = 0;
}

销毁队列,释放空间:

void Destory( Queue *Q ) {
    Q -> maxSize = 0;
    free( Q -> element );
    Q -> front = Q -> rear = -1;
}

判断队列是否为空:

bool IsEmpty( Queue *Q ) {
    return Q -> front == Q -> rear;
}

判断队列是否满:

bool IsFull( Queue *Q ) {
    return ( Q -> rear + 1 ) % Q -> maxSize = Q -> front;
}

获取队头元素:

bool Front( Queue *Q , ElemType *x ) {
    if( IsEmpty( Q ) ) {
        return false;
    }
    *x = Q -> element[ ( Q -> front + 1 ) % Q -> maxSize ];
    return true;
}

队尾插入元素(入队):

bool EnQueue( Queue *Q , ElemType x ) {
    if( IsFull( Q ) ) {
        return false;
    }
    Q -> rear = ( Q -> rear + 1 ) % Q -> maxSize;
    Q -> element[ Q -> rear ] = x;
    return true;
}

删除队头元素(出队):

bool DeQueue( Queue *Q ) {
    if( IsEmpty( Q ) ) {
        return false;
    }
    Q ->front = ( Q -> front + 1 ) % Q -> maxSize;
    return true;
}

清除队列中全部元素,不释放空间:

void Clear( Queue *Q ) {
    Q -> front = Q -> rear = 0;
}

队列判断条件:

( Q -> rear + 1 ) % Q -> maxSize = Q -> front;	//队满条件
Q -> front == Q -> rear;	//队空条件
( Q -> rear - Q -> front + maxSize ) % maxSize;	//元素个数
&3.2.3 链式队列

链式存储类型定义:

typedef struct {
	ElemType data;
    struct LinkNode *next;
} LinkNode;
typedef struct {
    LinkNode *front , *rear;
}

链式队列判断条件:

Q -> front == Q -> rear == NULL;

初始化:

void InitQueue( LinkQueue &Q ) {
	Q -> front = Q -> rear = ( LinkNode *) malloc ( sizeof( LinkNode ) );
	Q -> front -> next = NULL;
}

判队空:

bool IsEmpty( LinkQueue Q ) {
    if( Q -> front == Q -> rear ) {
        return true;
    } else {
        return false;
    }
}

入队:

void EnQueue( LinkQueue &Q , ElemType x ) {
    LinkNode *s = ( LinkNode *) malloc ( sizeof( LinkNode ) );
    s -> data = x;
    s -> next = NULL;
    Q -> rear -> next = s;
    Q -> rear = s;
}

出队:

bool DeQueue( LinkQueue &Q , ElemType &x ) {
    if( Q -> front == Q -> rear ) {
        return false;
    }
    LinkNode *p = Q -> front -> next;
    if( Q -> rear == p ) {
        Q -> rear = Q -> front;
    }
    free( p );
    return true;
}

&4 数组和字符串

&4.1 稀疏矩阵
&4.1.1 定义
#define maxsize 100
typedef int ElemType;
typedef struct term {
    int col , row;
    ElemType value;
} Term;
typedef struct sparsematrix {
    int m , n , t;
    Term table[ maxSize ];
} SparseMatrix;
&4.1.2 快速转置
for( int j = 0 ; j < n ; j++ ) {
	num[ j ] = 0;
}
for( int i = 0 ; i < t ; i++ ) {
    num[ A.table[ i ].col ]++;
}

for( int j = 0 ; j < n ; j++ ) {
	k[ j ] = 0;
}
for( int j = 1 ; j < n ; j++ ) {
    k[ j ] = k[ j - 1 ] + num[ j - 1 ];
}

for( int i = 0 ; i < t ; i++ ) {
    int index = k[ A.table[ i ].col ]++;
    B.table[ index ].col = A.table[ i ].row;
    B.table[ index ].row = A.table[ i ].col;
    B.table[ index ].value = A.table[ i ].value;
}
&4.2 字符串
&4.2.1 串的定义

定长顺序存储表示:

#define MAXLEN 255
typedef struct {
    char ch[ MAXLEN ];
    int length;
} SString;

堆分配存储表示:

typedef struct {
	char *ch;
	int length;
} HString;
&4.2.2 模式匹配
&4.2.2.1 简单模式匹配
int Index( SString S , SString T ) {
    int i = 1 , j = 1;
    while( i <= S.length && j <= T.length ) {
        if( S.ch[ i ] == T.ch[ j ] ) {
            ++i;
            ++j;
        } else {
            i = i - j + 2;
            j = 1;
        }
    }
    if( j > T.length ) {
        return i - T.length;
    } else {
        return 0;
    }
}
&4.2.2.2 改进字符串匹配(KMP)
P( 0 , k - 1 ) = S( i - k , i - 1 );

next数组求解:

void get_next( String T , int next[] ) {
    int j = 0 , k = 0;
    next[ 0 ] = 0;
    while( j < T.length ) {
        if( k == -1 || T.ch[ j ] == T.ch[ k ] ) {
            j++;
            k++;
            next[ j ] = k;
        } else {
            k = next[ k ];
        }
    }
}

KMP算法:

int Index_KMP( String S , String T , int* next ) {
    int i = 1 , j = 1;
    while( i <= S.length && j <= T.length ) {
        if( j == 0 || S.ch[ i ] == T.ch[ j ] ) {
            ++i;
            ++j;
        } else {
            j = next[ j ];
        }
    }
    if( j > T.length ) {
        return i - T.length;
    } else {
        return 0;
    }
}
&4.2.2.3 KMP进一步优化

next数组修正值算法:

void get_nextval( String T , int nextval ) {
    int i = 1 , j = 0;
    nextval[ 1 ] = 0;
    while( i < T.length ) {
        if( j == 0 || T.ch[ i ] == T.ch[ j ] ) {
            ++i;
            ++j;
            if( T.ch[ i ] != T.ch[ j ] ) {
                nextval[ i ] = j;
            } else {
                nextval[ i ] = nextval[ j ];
            } 
        } else {
            j = nextval[ j ];
        }
    }
}

&5 树与二叉树

&5.2 二叉树

链式存储结构:

typedef struct BiTNode {
    ElemType data;
    struct BiTNode *lchild , *rchild;
} BiTNode , *BiTree;
&5.3 二叉树遍历
&5.3.1 递归
&5.3.1.1 先序遍历
void PreOrder( BiTree T ) {
    if( T != NULL ) {
        visit( T );
        PreOrder( T -> lchild );
        PreOrder( T -> rchild );
    }
}
&5.3.1.2 中序遍历
void InOrder( BiTree T ) {
    if( T != NULL ) {
        InOrder( T -> lchild );
        visit( T );
        InOrder( T -> rchild );
    }
}
&5.3.1.3 后序遍历
void PostOrder( BiTree T ) {
    if( T != NULL ) {
        PostOrder( T -> lchild );
        PostOrder( T -> rchild );
        visit( T );
    }
}
&5.3.2 非递归
&5.3.2.1 中序遍历
void InOrder2( BiTree T ) {
    InitStack( S );
    BiTree p = T;
    while( p || !IsEmpty( S ) ) {
        if( p ) {
            Push( S , p );
            p = p -> lchild;
        } else {
            Pop( S , p );
            visit( p );
            p = p -> rchild;
        }
    }
}
&5.3.2.2 先序遍历
void PreOrder2( BiTree T ) {
    InitStack( S );
    BiTree p = T;
    while( p || !IsEmpty( S ) ) {
        if( p ) {
            visit( p );
            Push( S , p );
            p = p -> lchild;
        } else {
            Pop( S , p );
            p = p -> rchild;
        }
    }
}
&5.3.2.3 后序遍历
void PostOrder2( BiTree T ) {
    InitStack( S );
    BiTree p = T;
    BiTree r = NULL;
    while( p || !IsEmpty( S ) ) {
		if( p ) {
            Push( S , p );
            p = p -> lchild;
        } else {
            GetTop( S , p );	//只读不取
            if( p - > rchild && p -> rchild != r ) {	//右结点没被访问过
                p =  p -> rchild;
            } else {
                Pop( S , p );
                visit( p );
                r = p;
                p = NULL;
            }
        }
    }
}
&5.3.3 层次遍历
void LevelOrder( BiTree T ) {
    InitQueue( Q );
    BiTree p;
    EnQueue( Q , T );
    while( !IsEmpty( Q ) ) {
        DeQueue( Q , p );
        visit( p );
        if( p -> lchild != NULL ) {
            EnQueue( Q , p -> lchild );
        }
        if( P -> rchild != NULL ) {
            EnQueue( Q , p -> rchild );
        }
    }
}
&5.4 线索二叉树
&5.4.1 存储结构
typedef struct ThreadNode {
    ElemType data;
    struct ThreadNode *lchild , *rchild;
    int ltag , rtag;
} ThreadNode , *ThreadTree;
&5.4.2 线索化

中序遍历递归线索化:

void InThread( ThreadTree &p , ThreadTree &pre ) {
    if( p != NULL ) {
        InThread( p -> lchild , pre );
        if( p -> lchild == NULL ) {
            p -> lchild = pre;
            p -> ltag = 1;
        }
        if( pre != NULL && pre -> rchild == NULL ) {
            pre -> rchild = p;
            pre -> rtag = 1;
        }
        pre = p;
        InThread( p -> rchild , pre );
    }
}

void CreateInThread( ThreadTree T ) {
    ThreadTree pre = NULL;
    if( T != NULL ) {
        InThread( T , pre );
        pre -> rchild = NULL;
        pre -> rtag = 1;
    }
}
&5.4.3 遍历

中序序列第一个结点:

ThreadNode *Firstnode( ThreadNode *p ) {
    while( p -> ltag == 0 ) {
        p = p -> lchild;
        return p;
    }
}

结点p在中序序列下的后续:

ThreadNode *Nextnode( ThreadNode *p ) {
    if( p -> rtag == 0 ) {
        return Firstnode( p -> rchild );
    } else {
        return p -> rchild;
    }
}

中序序列最后一个结点:

ThreadNode *Lastnode( ThreadNode *p ) {
    while( p -> rtag == 0 ) {
        p = p -> rchild;
        return p;
    }
}

结点p在中序序列下的前驱:

ThreadNode *Prenode( ThreadNode *p ) {
    if( p -> ltag == 0 ) {
        return Firstnode( p -> lchild );
    } else {
        return p -> lchild;
    }
}
&5.5 树、森林
&5.5.1 树的存储结构
&5.5.1.1 双亲表示法
#define MAX_TREE_SIZE 100
typedef struct {
    ElemType data;
    int parent;
} PTNode;
typedef struct {
    PTNode nodes[ MAX_TREE_SIZE ];
    int n;
} PTree;
&5.5.1.2 孩子兄弟表示法
typedef struct CSNode {
    ElemType data;
    struct CSNode *firstchild , *nextsibling;
} CSNode , *CSTree;
&5.6 树、二叉树应用
&5.6.1 二叉排序树

二叉排序树非递归查找:

BSTNode *BST_Search( BiTree T , ElemType key ) {
    while( T != NULL && key != T -> data ) {
        if( key < T -> data) {
            T = T -> lchild;
        } else {
            T = T -> rchild;
        }
    }
    return T;
}

插入:

int BST_Insert( BiTree &T , KeyType k ) {
    if( T == NULL ) {
        T = ( BiTree ) malloc ( sizeof( BSTNode ) );
        T -> key = k;
        T -> lchild = T -> rchild = NULL;
        return 1;
    } else if( k == T -> key ) {
        return 0;
    } else if( k < T -> key ) {
        return BST_Insert( T -> lchild , k );
    } else {
        return BST_Insert( T -> rchild , k );
    }
}

构造:

void Creat_BST( BiTree &T , KeyType str[] , int n ) {
    T = NULL;
    int i = 0;
    while( i < n ) {
        BST_Insert( T , str[ i ] );
        i++;
    }
}
&5.6.2 平衡二叉树

插入:

1)LL平衡(左孩子的左子树不平衡):左孩子替代根节点,根节点变为右子树根节点
2)RR平衡(右孩子的右子树不平衡):右孩子替代根节点,根节点变为左子树根节点
3)LR平衡(左孩子的右子树不平衡):左孩子的右子树根节点替代左孩子,再替代根节点,根节点变为右子树根节点
4)RL平衡(右孩子的左子树不平衡):右孩子的左子树根节点替代右孩子,再替代根节点,根节点变为左子树根节点

&6 图

&6.1 图的存储及操作
&6.1.1 邻接矩阵

存储结构:

#define MaxVertxNum 100
typedef char VertexType;
typedef int EdgeType;
typedef struct {
    VertexType Vex[ MaxVertexNum ];		//顶点表
    EdgeType Edge[ MaxVertexNum ][ MaxVertNum ];
    int vexnum , arcnum;
}
&6.1.2 邻接表法

存储结构:

#define MaxVertxNum 100
typedef struct ArcNode {	//边表结点
    int adjvex;
    struct ArccNode *next;
} ArcNode;
typedef struct VNode {		//顶点表结点
    VertexType data;
    ArcNode *first;
} VNode , AdjList[ MaxVertxNum ];
typedef struct {
    AdjList vertices;
    int vexnum , arcnum;
} ALGraph;
&6.2 图的遍历
&6.2.1 广度优先搜索
&6.2.1.1 搜索算法伪代码
bool visited[ MAX_VERTEX_NUM ];
void BFSTraverse( Graph G ) {
    for( i = 0 ; i < G.vexnum ; ++i ) {
        visited[ i ] = FALSE;
    }
    InitQueue( Q );
    for( i = 0 ; i < G.vexnum ; ++i ) {
        if( !visited[ i ] ) {
            BFS( G , i );
        }
    }
}
void BFS( Graph G , int v ) {
    visit( v );
    visited[ v ] = true;
    EnQueue( Q , v );
    while( !IsEmpty( Q ) ) {
        DeQueue( Q , v );
        for( w = FirstNeighbor( G , v ) ; w >= 0 ; w = NextNeighbor( G ,v ,w ) ) {
            if( !visited[ w ] ) {
                visit( w );
                visited[ w ] = true;
                EnQueue( Q , w );
            }
        }
    }
}
&6.2.1.2 BFS求解单源最短路径
void BFS_MIN_Distance( Graph G , int u ) {
    for( i = 0 ; i < G.vexnum ; ++i ) {
        d[ i ] =;
    }
    visited[ u ] = true;
    d[ u ] = 0;
    EnQueue( Q , u );
    while( !IsEmpty( Q ) ) {
        DeQueue( Q , u );
        for( w = FirstNeighbor( G , u ) ; w >= 0 ; w = NextNeighbor( G , u ,w ) ) {
            if( !visited[ w ] ) {
                visited[ w ] = true;
                d[ w ] = d[ u ] + 1;
                EnQueue( Q , w );
            }
        }
    }
}
&6.2.2 深度优先搜索
&6.2.2.1 搜索算法伪代码

递归:

bool visited[ MAX_VERTEX_NUM ];
void DFSTraverse( Graph G ) {
    for( v = 0 ; v < G.vexnum ; ++v ) {
		visited[ v ] = false;
    }
    for( v = 0 ; v < G.vexnum ; ++v ) {
        if( !visited[ v ] ) {
            DFS( G , v );
        }
    }
}
void DFS( Graph G , int v ) {
    visit( v );
    visited[ v ] = true;
    for( w = FirstNeighbor( G , v ) ; w >= 0 ; w = NextNeighbor( G , v ,w ) ) {
        if( !visited[ w ] ) {
            DFS( G , w );
        }
    }
}

非递归:

void DFS_Non_RC( AGraph &G , int v ) {
    int w;
    InitStack( S );
    for( i = 0 ; i < G.vexnum ; i++ ) {
        visited[ i ] = false;
    }
    Push( S , v );
    visited[ v ] = true;
    while( !IsEmpty( S ) ) {
        k = Pop( S );
        visit( k );
        for( w = FirstNeighbor( G , k ) ; w >= 0 ; w = NextNeighbor( G , k , w ) ) {
            if( !visited[ w ] ) {
                Push( S , w );
                visited[ w ] = true;
            }
        }
    }
}
&6.2.2.2 输出所有简单路径
void FindPath( AGraph &G , int u , int v , int path[] , int d ) {
    int w , i;
    ArcNode *p;
    d++;
    path[ d ] = u;
    visited[ u ] = 1;
    if( u == v ) {
        print( path[] );
    }
    p = G -> agjlist[ u ].firstarc;
    while( p != NULL ) {
        w = p -> adjvex;
        if( visited[ w ] == 0 ) {
            FindPath( G , w , v , path , d );
        }
        p = p -> nextarc;
    }
    visited[ u ] = 0;
}
&6.3 图的应用
&6.3.1 最小生成树
&6.3.1.1 通用最小生成算法

伪代码:

GENERIC_MST( G ) {
    T = null;
    while T 未形成一棵生成树;
    	do 找到一条最小代价边(u,v)并且加入T后不会产生回路;
    		T = T∪(u,v);
}
&6.3.1.2 Prim算法(普里姆)

简单实现:

void Prim( G , T ) {
    T = 空集;
    U = { w };
    while( ( V - U ) != 空集) {(u,v)是使u属于U与v属于(V-U),且权值最小的边;
        T = T ∪ {(u,v)};		//边归入树
        U = U ∪ { v };			//顶点归入树
    }
}
&6.3.1.3 Kruskal算法(克鲁斯卡尔)

简单实现:

void Kruskal( V , T ) {
    T = V;
    numS = n;
    while( numS > 1 ) {
        从E中取出权值最小的边(u,v);
        if(v和u属于T的不同的连通分量){
            T = T ∪ {(u,v)};		//边归入树
            numS--;
        }
    }
}
&6.3.2 拓扑排序

排序算法:

bool TopologicalSort( Graph G ) {
    InitStack( S );
    for( int i = 0 ; i < G.vexnum ; i++ ) {
        if( indegree[ i ] == 0 ) {		//计入所有度为0的顶点进栈
            Push( S , i );
        }
    }
    int count = 0;
    while( !IsEmpty( S ) ) {
        Pop( S , i );
        print[ count++ ] = i;
        for( p = G.vertices[ i ].firstarc ; p ; p = p -> nextarc ) {
            v = p -> adjvex;
            if( !( --indegree[ v ] ) ) {		//i指向的顶点入度减1,为0的顶点压入栈S
                Push( S , v );
            }
        }
    }
    if( count < G.vexnum ) {
        return false;
    } else {
        return true;
    }
}
&6.4 归纳总结
&6.4.1 取邻接顶点的下一个邻接顶点

邻接矩阵:

int NextNeighbor( MGraph &G , int x , int y ) {
    if( x != -1 && y != -1 ) {
        for( int col = y + 1 ; col < G.vexnum ; col++ ) {
            if( G.Edge[ x ][ col ] > 0 && G.Edge[ x ][ col ] < maxWeight ) {
                return col;
            }
        }
        return -1;
    }
}

邻接表:

int NextNeighbor( ALGraph &G , int x , int y ) {
    if( x != -1 ) {
        ArcNode *p = G.vertices[ x ].first;
        while( p != NULL && p -> data != y ) {
            p = p -> next;
        }
        if( p != NULL && p -> next != NULL ) {
            return p -> next -> data;
        }
    }
    return -1;
}

&7 查找

&7.1 顺序查找和折半查找
&7.1.1 一般线性表的顺序查找
typedef struct {
    ElemType *elem;
    int TableLen;
} SSTable;
int Search_Seq( SSTable ST , ElemType key ) {
    ST.elem[ 0 ] = key;
    for( i = ST.TableLen ; ST.elem[ i ] != key ; --i ) {
        return i;
    }
}
&7.1.2 折半查找

非递归:

int Binary_Search( SeqList L , ElemType key ) {
    int low = 0 , high = L.TableLen - 1 , mid;
    while( low <= high ) {
        mid = ( low + high ) / 2;
        if( L.elem[ mid ] == key ) {
            return mid;
        } else if( L.elem[ mid ] > key ) {
            high = mid - 1;
        } else {
            low = mid + 1;
        }
    }
    return -1;
}

递归:

typedef struct {
    ElemType *elem;
    int length;
} SSTable;
int BinSearchRec( SSTable ST , ElemType key , int low , int high ) {
    if( low > high ) {
        return 0;
    }
    mid = ( low + high ) / 2;
    if( key > ST.elem[ mid ] ) {
        Search( ST , key , mid + 1 , high );
    } else if( key < ST.elem[ mid ] ) {
        Search( ST , key , low , mid - 1 );
    } else {
        return mid;
    }
}

&8 排序

&8.1 插入排序
&8.1.1 直接插入排序
void InsertSort( ElemType A[] , int n ) {
    int i , j;
    for( i = 2 ; i <= n ; i++ ) {
        if( A[ i ] < A[ i - 1 ] ) {
            A[ 0 ] = A[ i ];
            for( j = i - 1 ; A[ 0 ] < A[ j ] ; --j ) {
                A[ j + 1 ] = A[ j ];		//检测的位置在插入位置的前一个位置
            }
            A[ j + 1 ] = A[ 0 ];
        }
    }
}
&8.1.2 折半插入排序
void InsertSort( ElemType A[] , int n ) {
    int i , j , low , high , mid;
    for( i = 2 ; i < n ; i++ ) {
        A[ 0 ] = A[ i ];
        low = 1;
        high = i - 1;
        while( low <= high ) {
            mid = ( low + high ) / 2;
            if( A[ mid ] > A[ 0 ] ) {
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }
        for( j = i - 1 ; j >= high + 1 ; --j ) {
            A[ j + 1 ] = A[ j ];
        }
        A[ high + 1 ] = A[ 0 ];
    }
}
&8.1.3 希尔排序
void ShellSort( ElemType A[] , int n ) {
    for( dk = n / 2 ; dk >= 1 ; dk = dk / 2 ) {		//步长变化
        for( i = dk + 1 ; i <= n ; ++i ) {		//从第一个步长开始遍历
            if( A[ i ] < A[ i - dk ] ) {
                A[ 0 ] = A[ i ];
                for( j = i - dk ; j > 0 && A[ 0 ] < A[ j ] ; j -= dk ) {	//交换后移
                    A[ j + dk ] = A[ j ];
                }
                A[ j + dk ] = A[ 0 ];		//插入
            }
        }
    }
}
&8.2 交换排序
&8.2.1 冒泡排序
void BUbbleSort( ElemType A[] , int n ) {
	for( i = 0 ; i < n - 1 ; i ++ ) {
		flag = false;
		for( j = n - 1 ; j > i ; j-- ) {
			if( A[ j - 1 ] > A[ j ] ) {
                swap( A[ j - 1 ] , A[ j ] );
                flag = true;
            }
		}
        if( flag == false ) {
            return;
        }
	}
}
&8.2.2 快速排序
void QuickSort( ElemType A[] , int low ,int high ) {
    if( low < high ) {
        int pivotpos = Partition( A , low , high );
        QuickSort( A , low , pivotpos - 1 );
        QuickSort( A , pivotpos + 1 , high );
    }
}

int Partition( ElemType A[] , int low ,int high ) {
    ElemType pivot = A[ low ];
    while( low < high ) {
        while( low < high && A[ high ] >= pivot ) {
            high--;
        }
        A[ low ] = A[ high ];
        while( low < high && A[ low ] <= pivot ) {
            low++;
        }
        A[ high ] = A[ low ];
    }
    A[ low ] = pivot; //小于low均小于pivot,大于low均大于pivot
    return low;
}
&8.3 选择排序
&8.3.1 简单选择排序
void SelectSort( ElemType A[] , int n ) {
    for( i = 0 ; i < n - 1 ; i++ ) {
        min = i;
        for( j = i + 1 ; j < n : j++ ) {
            if( A[ j ] < A[ min ] ) {
                min = j;
            }
        }
        if( min != i ) {
            swap( A[ i ] , A[ min ] );
        }
    }
}
&8.3.2 堆排序

建立大根堆:

void BuildMaxHeap( ElemType A[] , int len ) {
    for( int i = len / 2 ; i > 0 ; i-- ) {
        HeadAdjust( A , i , len );
    }
}
void HeadAdjust( ElemType A[] , int k , int len ) {
	A[ 0 ] = A[ k ];
    for( i = 2 * k ; i <= len ; i *= 2 ) {
        if( i < len && A[ i ] < A[ i + 1 ] ) {
            i++;
        }
        if( A[ 0 ] >= A[ i ] ) {
            break;
        } else {
            A[ k ] = A[ i ];
            k = i;
        }
    }
    A[ k ] = A[ 0 ];
}

排序算法:

void HeadSort( ElemType A[] , int len ) {
    BuildMaxHeap( A , len );
    for( i = len ; i > 1 ; i-- ) {
        Swap( A[ i ] , A[ 1 ] );
        HeadAdjust( A , 1 , i - 1 );
    }
}
&8.4 归并排序和基数排序
&8.4.1 归并排序

两个有序表排序成一个有序表:

ElemType *B = ( ElemType *) malloc ( ( n + 1 ) * sizeof( ElemType ) );
void Merge( ElemType A[] , int low , int mid , int high ) {
    for( int k = low ; k <= high ; k++ ) {
        B[ k ] = A[ k ];
    }
    for( i = low , j = mid + 1 , k = i ; i <= mid && j <= high ; k++ ) {
        if( B[ i ] <= B[ j ] ) {
            A[ k ] = B[ i++ ];
        } else {
            A[ k ] = B[ j++ ];
        }
    }
    while( i <= mid ) {
        A[ k++ ] = B[ i++ ];
    }
    while( j <= high ) {
        A[ k++ ] = B[ j++ ];
    }
}

合并已排序的子表:

void MergeSort( ElemType A[] , int low , int high ) {
    if( low < high ) {
        int mid = ( low + high ) / 2;
        MergeSort( A , low , mid );
        MergeSort( A , mid + 1 , high );
        Merge( A , low , mid , high );
    }
}
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值