My code is beyond stackoverflow characters limit. So see https://gist.github.com/redguardtoo/78a68fb6ac914bd89b6f04314819d24b for full code.
Here is a short version,
"一" 375 ;; 375 corresponds to pinyin of one hanzi
;; ... skipped ...
(defun my-chinese-compare (w1 w2)
(let ((i 0)
(max-len (min (length w1) (length w2)))
(while (and (not break) (< i max-len))
(setq v1 (gethash (substring-no-properties w1 i (1+ i)) my-chinese-pinyin-order-hash 9999))
(setq v2 (gethash (substring-no-properties w2 i (1+ i)) my-chinese-pinyin-order-hash 9999))
(unless (eq v1 v2)
(setq rlt (< v1 v2))
(setq break t))
(setq i (1+ i)))
((eq i max-len)
(eq max-len (length w1)))
(defun my-chinese-sort-word-list (word-list)
(sort word-list #'my-chinese-compare)))
(message "test: %s" (my-chinese-sort-word-list '("小明" "小红" "张三" "李四" "王二" "大李" "古力娜扎" "迪丽热巴")))
I've contributed patches to he most popular Chinese IME pyim (https://github.com/tumashu/pyim) recently. So I'm familiar with Hanzi (Chinese character) processing. For example, I know https://github.com/tumashu/pyim-basedict provides a dictionary contains all the Chinese characters which are already sorted by pinyin.
My code sort the charcter by its number. The number is roughly the line number of the character's pinyin in pyim-basedict's dictionary file.
In my code, I only sorted the word by 2,500 mostly used Chinese characters which is PRC national standard (https://www.zdic.net/zd/zb/cc1/).