A simple solution is to create an octet or kd tree with all the points, and then use it to find the nearest point for each point. This is O (N * log N) for the middle case.
A faster solution, which, in my opinion, is O (N) for the average case, can be implemented taking into account the following idea:
If you divide the space by half (say, on some plane aligned along the axis), you will get points divided into two subsets: A and B, and the two closest points can be either in A or in B or in one of A and one in B.
So, you need to create a queue of pairs of three-dimensional boxes ordered by the minimum distance between them, and then:
1) Select the first pair of cells from the queue
2) If both fields are the same field A, divide it in half into two fields B and C and insert the pairs (B, B), (C, C) and (B, C) in the queue.
3) If they are different (A, B), divide the largest (for example, B) half, receiving boxes C and D and inserting pairs (A, C) and (A, D) into the queue.
4) Repeat.
In addition, when the number of points within a pair of cells goes below a certain threshold, you can use brute force to search for the nearest pair of points.
The search stops as soon as the distance between the two cells in the pair above is greater than the minimum distance found so far.