数据结构考前小练习--py

一、假设非空二叉树采用二叉链存储结构,所有结点值均不相同,根结点为b,结点类型如下:

class BTNode:    #二叉链中结点类
def __init__(self,d=None):          #构造方法
self.data=d       #结点值
self.lchild=None          #左孩子指针
self.rchild=None          #右孩子指针

设计一个算法判断其中值为x的结点与值为y的结点是否为兄弟结点,若是兄弟结点返回True,否则返回False。

采用先序遍历法进行二叉树的遍历 

class BTNode:
    def __init__(self, data=None):
        self.data = data
        self.lchild = None
        self.rchild = None


# 非满二叉树
b = BTNode('A')
p1 = BTNode('B')
p2 = BTNode('C')
p3 = BTNode('D')
p4 = BTNode('E')
p5 = BTNode('F')
p6 = BTNode('G')
# connect
b.lchild = p1
b.rchild = p2
p1.lchild = p3
p3.rchild = p6
p2.lchild = p4
p2.rchild = p5


# 满二叉树
b2 = BTNode('A')
p1_2 = BTNode('B')
p2_2 = BTNode('C')
p3_2 = BTNode('D')
p4_2 = BTNode('E')
p5_2 = BTNode('F')
p6_2 = BTNode('G')

b2.lchild = p1_2
b2.rchild = p2_2
p1_2.lchild = p3_2
p1_2.rchild = p4_2
p2_2.lchild = p5_2
p2_2.rchild = p6_2


# 判断其中值为x的结点与值为y的结点是否为兄弟结点
def brother(b, x, y):
    '''先序遍历'''
    if b == None:
        return False
    # 判断
    if b.lchild != None and b.rchild != None:
        if (b.lchild.data == x and b.rchild.data == y) or (b.lchild.data == y and b.rchild.data == x):
            return True
    # 继续遍历左子树
    tag = brother(b.lchild, x, y)
    if tag:
        return True
    else:
        # 遍历右子树
        return brother(b.rchild, x, y)


print(brother(b, 'D', 'G'))

二、有一棵非空满二叉树采用二叉链存储,结点类型如下: class BTNode:#二叉链中结点类 def __init__(self,d=None): #构造方法 self.data=d#结点值 self.lchild=None #左孩子指针 self.rchild=None #右孩子指针 设计一个尽可能高效的算法求根结点为b的满二叉树的结点个数 

满二叉树的结点个数为2的n(二叉树的高度h)次方减1

h通过迭代遍历二叉树左子树获取

# 求根结点为b的满二叉树的结点个数
def node_num(b):
    '''
        满二叉树的结点数为2的h次方(h)减一
    '''
    h = 1
    p = b
    while p.lchild != None:
        h += 1
        p = p.lchild
    return 2 ** h - 1


print('该满二叉树的结点数为:', node_num(b2))

三、假设一个无向图是非连通的,采用邻接表作为存储结构,试设计一个算法,输出图中各连通分量的顶点序列 

INF = 0x3f3f3f
'''
    一个非连通的无向图,采用邻接表为存储结构
'''

'''
    输出图中各连通分量的顶点序列
'''

MAXV = 100                # 最多顶点个数
visited = [0] * MAXV      # 标记
a = [
    [0, 0, 0, 0, 0],
    [0, 0, 1, 1, 1],
    [0, 1, 0, 1, 1],
    [0, 1, 1, 0, 1],
    [0, 1, 1, 1, 1]
]
n = 5
e = 7


class ArcNode:
    '''边结点'''
    def __init__(self, adjv, w):
        self.adjv = adjv          # 邻接点
        self.weight = w           # 边的权重


class AdjGraph:
    '''根据邻接矩阵构建邻接表'''
    def __init__(self, n=0, e=0):
        self.adjust = []          # 邻接表数组
        self.vexs = []            # 存放顶点i的信息
        self.n = n                # 顶点数
        self.e = e                # 边数

    def CreateAdjGraphh(self, a, n, e):
        self.n = n
        self.e = e
        for i in range(n):
            adi = []              # 存放顶点i的邻接点,初始为空
            for j in range(n):
                if a[i][j] != 0 and a[i][j] != INF:
                    p = ArcNode(j, a[i][j])
                    adi.append(p)
            self.adjust.append(adi)

    def DispAdjGraph(self):
        for i in range(self.n):
            print(" [%d]" % (i), end='')
            for p in self.adjust[i]:
                print("->(%d, %d)" % (p.adjv, p.weight), end='')
            print("->^")


Graph = AdjGraph(n, e)
Graph.CreateAdjGraphh(a, n, e)
Graph.DispAdjGraph()


def DFS(adjust, v, cc):
    '''在邻接表G中从顶点v出发的深度优先遍历'''
    # print(v, end='')
    visited[v] = 1
    cc.append(v)
    for j in range(len(adjust[v])):
        w = adjust[v][j].adjv
        if visited[w] == 0:
            DFS(adjust, w, cc)


def connected_compoents(adjust):
    compoents = []                     # 存储所有连通分量
    for v in range(len(adjust)):
        if not visited[v]:
            cc = []                    # 创建一个连通分量
            DFS(adjust, v, cc)
            compoents.append(cc)
    return compoents


print(connected_compoents(Graph.adjust))

 四、

有两个递增有序表,所有元素为整数,均采用带头结点的单链表存储,结点类型定义如下:
class LinkNode:                      #单链表结点类
def __init__(self,data=None):       #构造函数
self.data=data                  #data属性
    self.next=None                  #next属性
设计一个尽可能高效的算法,将两个递增有序单链表A、B(A、B分别为两个有序单链表的头结点)合并为一个递减有序单链表hc,要求算法空间复杂度为O(1)。
'''
    将两个递增有序单链表A、B合并为一个递减有序单链表hc,时间复杂度为O(1)
'''


class LinkNode:
    def __init__(self, data=None):
        self.data = data
        self.next = None


class LinkList:
    def __init__(self):
        self.head = LinkNode()
        self.head.next = None

    # 头插法
    def CreateList(self, a):
        for i in range(0, len(a)):
            s = LinkNode(a[i])
            s.next = self.head.next
            self.head.next = s

    def display(self):
        p = self.head.next
        while p is not None:
            print(p.data, end=' ')
            p = p.next
        print()


def merge(A, B):
    # 采用二路归并+头插法建表
    pa = A.next
    pb = B.next

    C = A
    C.next = None
    while pa != None and pb != None:
        if pa.data < pb.data:
            # 头插法
            q = pa.next
            pa.next = C.next
            C.next = pa
            pa = q
        else:
            q = pb.next
            pb.next = C.next
            C.next = pb
            pb = q
    if pb != None:
        pa = pb
    while pa != None:
        q = pa.next
        pa.next = C.next
        C.next = pa
        pa = q
    return C


if __name__ == "__main__":
    L = LinkList()
    L2 = LinkList()
    print("头插法建立单链表L")
    a = [10, 8, 6, 5, 3, 1]
    b = [11, 7, 4, 2, 0]
    L.CreateList(a)
    L2.CreateList(b)
    print("L:")
    L.display()
    print("L2:")
    L2.display()

    print("二路归并:")
    c = merge(L.head, L2.head)
    c = c.next
    while c is not None:
        print(c.data, end=' ')
        c = c.next

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值