As I understand your issue,
Another way of stating your problem is : "for each polygon i look for the smallest one that contains him".
Edit : As said by J. Monticolo, this will work only if your polygon overlaps.
Otherwise, you still can work with the St_ExteriorRing of your polygons (must be polygons not MultiGeometry) and apply the same traitment, not tested but should work.
Maybe there is some QGIS plug-in to do it simply, I don't know.
But I will give you a solution with Postgres/postgis, if you want to use it, you have to install postgres and then upload your shapefile in postgres.
And then use some Sql queries ...
If you go this way, you can make a query where you look if polygons are contained in other polygons. then you have couples of polygon, you just need to partition them in group and select the smallest one. So you can use Partition , ordering by area and partitioning by name, and you find what you want.
Exemple :

WITH contains AS (
SELECT t2.name AS container,
t1.name AS contained,
ST_AREA(t2.geom) AS area
FROM work.test_poly AS t2,
work.test_poly AS t1
WHERE ST_CONTAINS(t2.geom, t1.geom)
ORDER BY ST_AREA(t2.geom)
),
pair_polygons AS (
SELECT contains.container,
contained,
area AS area,
row_number() OVER(
PARTITION BY contained
ORDER BY area) AS cluster
FROM contains
WHERE container != contained
),
master_slave AS (
SELECT container,
contained,
cluster
FROM pair_polygons
WHERE cluster = 1
)
UPDATE work.test_poly
SET master = container
FROM master_slave
WHERE name = contained
;
poly_test is the name of my blank table and i use couple of CTE here
but you should be able to adapt =)
this will give you this :

I think there is also other ways to do it ...