Distribute values equally
Ok, here is my revised approach, using NTILE.  It actually gives roughly the same as your proposed output.  

declare @ships table
(
shipnr int,
portnr varchar(50)
);

insert into @ships (shipnr, portnr)
values (1, 'A'), (2, 'A'), (3, 'A'), (4, 'A'), (5, 'A'), (6, 'B'), (7, 'B'), (8, 'B'), (9, 'B'), (10, 'C'),
(11,'D'), (12, 'D'), (13, 'E'), (14, 'E'), (15, 'E'), (16, 'F'), (17, 'F'), (18, 'F'), (19, 'F'), (20, 'F') , (21, 'F') , (22, 'F') 

DECLARE @PortNumber INT = (SELECT COUNT(DISTINCT portnr) FROM @ships) - 1

;WITH CTE_Ships AS
    (
    SELECT S.shipnr
        , S.portnr
        , NT = NTILE(@PortNumber) OVER (PARTITION BY portnr ORDER BY (portnr))
    FROM @ships AS S
    )

SELECT * FROM CTE_Ships ORDER BY NT, portnr