基于两个值对链表进行排序

时间:2021-04-02 16:14:54

标签: python linked-list

我有一个单向链表,其中数据是我创建的一个自定义对象,名为“Patient”,我根据“Patient.points”对链表进行排序。

但是,如果被比较的两个患者具有相同的点数,我还想按“Patient.bmi”对列表进行排序,作为辅助过滤器。

我希望通过 BMI 过滤器对患者进行排序的方式是让 bmi 最差的患者按升序排列。我有四种“状况”,“肥胖、超重、体重不足和正常”。我希望肥胖、超重和正常按降序排列,体重不足按升序排列。

这是我的链表:

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

class LinkedList:
    def __init__(self):
        self.head = None

    def addNode(self, data):
        curr = self.head
        if curr is None:
            n = Node()
            n.data = data
            self.head = n
            return

        if curr.data.points == data.points and curr.data.condition == 'underweight':
            if curr.data.bmi > data.bmi:
                n = Node()
                n.data = data
                n.next = curr
                self.head = n
                return
        elif curr.data.points == data.points and curr.data.condition != 'underweight':
            if curr.data.bmi < data.bmi:
                n = Node()
                n.data = data
                n.next = curr
                self.head = n
                return

        if curr.data.points < data.points:
            n = Node()
            n.data = data
            n.next = curr
            self.head = n
            return

        while curr.next is not None:
            if curr.next.data.points < data.points:
                break
            curr = curr.next
        n = Node()
        n.data = data
        n.next = curr.next
        curr.next = n
        return

    def __str__(self):
        data = []
        curr = self.head
        while curr is not None:
            data.append(curr.data)
            curr = curr.next
        return "[%s]" %(', '.join(str(i) for i in data))

    def __repr__(self):
        return self.__str__()

这是返回的数据:

Paitent name: BDF237    age: 79 Years 2 Months 14 Days      BMI: 37.960398071201396     weight classification: obese
Paitent name: ABE127    age: 20 Years 6 Months 20 Days      BMI: 34.54054238911118      weight classification: obese
Paitent name: ABD721    age: 73 Years 4 Months 25 Days      BMI: 31.217481789802285     weight classification: obese
Paitent name: DED567    age: 58 Years 5 Months 5 Days       BMI: 32.74416118146279      weight classification: obese
Paitent name: DEF444    age: 24 Years 11 Months 25 Days     BMI: 31.462672275229988     weight classification: obese
Paitent name: BDF777    age: 93 Years 10 Months 11 Days     BMI: 14.705367459122582     weight classification: underweight
Paitent name: BDF098    age: 86 Years 0 Months 13 Days      BMI: 13.863739248528747     weight classification: underweight
Paitent name: DDC345    age: 54 Years 3 Months 19 Days      BMI: 16.45600644235146      weight classification: underweight
Paitent name: DDD222    age: 73 Years 9 Months 0 Days       BMI: 18.166204254194742     weight classification: underweight
Paitent name: DDD555    age: 66 Years 10 Months 0 Days      BMI: 17.632653061224488     weight classification: underweight

Paitent name: DEF666    age: 65 Years 10 Months 22 Days     BMI: 17.68978885166924      weight classification: underweight
Paitent name: ABE123    age: 69 Years 6 Months 19 Days      BMI: 28.010411951109102     weight classification: overweight
Paitent name: ABD111    age: 72 Years 8 Months 0 Days       BMI: 26.122448979591837     weight classification: overweight
Paitent name: ABE165    age: 23 Years 3 Months 9 Days       BMI: 26.491508201480624     weight classification: overweight
Paitent name: ABE329    age: 82 Years 0 Months 7 Days       BMI: 25.46401086464464      weight classification: overweight
Paitent name: DDD124    age: 44 Years 6 Months 27 Days      BMI: 27.15271058955713      weight classification: overweight
Paitent name: DED675    age: 45 Years 6 Months 29 Days      BMI: 28.735632183908045     weight classification: overweight
Paitent name: DED879    age: 22 Years 9 Months 1 Days       BMI: 28.73469387755102      weight classification: overweight
Paitent name: DEF555    age: 27 Years 1 Months 24 Days      BMI: 25.847768218818715     weight classification: overweight
Paitent name: ABC234    age: 19 Years 7 Months 19 Days      BMI: 23.057725694444446     weight classification: normal

Paitent name: ABD221    age: 50 Years 11 Months 0 Days      BMI: 21.872422819032593     weight classification: normal
Paitent name: ABD176    age: 55 Years 11 Months 3 Days      BMI: 21.132713440405748     weight classification: normal
Paitent name: ABD231    age: 55 Years 11 Months 29 Days     BMI: 20.9572742022715       weight classification: normal
Paitent name: ABD321    age: 59 Years 11 Months 9 Days      BMI: 20.429418362441915     weight classification: normal
Paitent name: ABD444    age: 57 Years 5 Months 6 Days       BMI: 20.820939916716245     weight classification: normal
Paitent name: ABD401    age: 63 Years 9 Months 22 Days      BMI: 21.513858510523864     weight classification: normal
Paitent name: ABD007    age: 22 Years 2 Months 17 Days      BMI: 21.62964876033058      weight classification: normal
Paitent name: ABC008    age: 83 Years 1 Months 19 Days      BMI: 19.77769866698311      weight classification: normal
Paitent name: ABC101    age: 86 Years 0 Months 13 Days      BMI: 18.556773222226116     weight classification: normal
Paitent name: ABC201    age: 26 Years 10 Months 7 Days      BMI: 20.303697560696612     weight classification: normal

我认为问题出在 while 类中的链表类中:

while curr.next is not None:
            if curr.next.data.points < data.points:
                break

但是,我不确定我需要将其调整为什么,尽管我知道它需要调整

非常感谢!

2 个答案:

答案 0 :(得分:1)

您不希望您的链表担心如何比较患者。只需覆盖患者类别的 < 运算符,这样比较两个患者就会自动给出您想要的顺序。

现在你的链表类不关心所有那些花哨的规则,因为它们应该由 Patient 类处理。链表只是检查

while curr.next is not None:
    if curr.next.data < data:
        break

这样做的方法是在 Patient 类上定义一个名为 __lt__ 的函数。字母“lt”是“小于”的缩写,在代码中使用“<”时会用到。同样,它会自动在排序中被引用。

另见Is it possible to overload the multiple comparison syntax in python?

这是一个快速演示:

import random

class Patient:

    def __init__(self, points, bmi):
        self.points = points
        self.bmi = bmi
        
    def __str__(self):
        return '{}, {}'.format(self.points, self.bmi)

    def __lt__(self, other):
        if self.points < other.points:
            return True
        if self.bmi < 18.5:
            if self.bmi > other.bmi:
                return True
        else:
            if self.bmi < other.bmi:
                return True
        return False

patients = [
    Patient(32, 25),
    Patient(32, 24),
    Patient(32, 18),
    Patient(32, 15),
    Patient(20, 25),
    Patient(20, 24),
    Patient(20, 18),
    Patient(20, 15),
]

random.shuffle(patients)
patients.sort()
for patient in patients:
    print(patient)
<块引用>

20、18
20、15
20、24
20、25
32、18
32、24
32、15
32、25

答案 1 :(得分:0)

定义 __lt__ 以按顺序比较条件:

def __lt__(self, other):
    if self.Points < other.Points:
        return True
    elif self.Points == other.Points:
        if self.bmi < other.bmi:
            return True
        else:
            return False
    else: # self.Points > other.Points
        return False
相关问题