Doubly linked lists. Singly linked lists and one-way trees work fine with the single ownership model.
As I've said before, the two places where Rust has problems with expressive power are backlinks and partially initialized arrays. Those are routine cases which are forced to unsafe code.
One of the places you most often need to use backlinks and other unsafe code in Rust is implementing fancy data structures. Unfortunately that happens to be what a lot of people think of as "programming" because they come up a lot in computer science classes... Fortunately most production code seldom needs new fancy data structures; maps, sets, tuples, structs and reference counting take you a very very long way. For less common things like graphs there are usually crates you can use off the shelf.
Backlinks ARE a very interesting point about Rust. Just because you don't find yourself using them all that often doesn't mean it's not interesting to the design and expresivity of the language.
The issue is a direct consequence of Rust's strict aliasing rules, which I feel any programmer would benefit from groking.
I think it's important to note that in the case of most data structures, you only need to do the hard work of verifying your unsafe code once, after which you can package it up in a crate.
I guess many C programmers might be used to reimplementing data structures for their programs, but I don't think it's useful in a majority of cases
Use of libraries may be more common in rust than c because of many possible factors:
1. Rust's standard library is large and contains data structures. People are good at centralizing on one thing if it's the standard one, if there are 10 competing string libraries, people might say "ah well, let's write our own". That also sometime means using one dependency will pull in others (e.g. in C you might want someone's regex library, but it might be incompatible with your string library because it uses a different one. A stdlib helps ensure libraries have a standard set of types to talk about, and C barely has that).
2. Rust's package manager (cargo) and registry (crates.io) are really good and making finding and adding dependencies much easier. If I want to add a random library on github to my rust project, it's 1 line in my Cargo.toml (whether it's on crates or not). In C, I have to figure out if they're using cmake, meson, autotools, or any of a dozen other things, and possibly vendor the code into a third_party folder, and possible spend several hours hacking on my build system to link against it.
3. Rust's community has made an effort to standardize on certain crates and include their use. See the rustlang nursery. The closest to this in C is stuff like the gnulib I think, which is an ancient effort pushing garbage code that suffers from the lack of good dependency management severely. I know of no recent similar efforts for C.
4. Rust has generics and a better type system in general which makes it much easier to implement generally usable libraries.
It's important to remember that C also predates the internet, and many c codebases also predate modern package management. Legacy practices have a habit of propagating themselves.
1. Storing an array and its length together and always checking it correctly such that you don't have a buffer overrun.
2. Freeing memory, not leaking memory.
3. Using a union correctly, e.g. always accessing the right variant.
4. Printing unicode characters.
5. Macros which dont' conflict with their scope (are hygenic)
All of those problems seem like they should be easy, are incredibly easy in rust, and are not fully solved problems in C.
I don't think rust makes easy problems harder just because its type-system and macro system and such are all so good compared to C.
It turns out having proper sum types instead of C's garbage unions, and having proper string support, and so on make easy problems easy too!