concept
For performance considerations, embedded systems are generally developed in C language. Since the C language standard library does not encapsulate linked lists, embedded systems generally design and implement the data structure of linked lists by themselves. Singly linked list is a type of linked list. This article describes the singly linked list defined by the HDF software module in OpenAtom OpenHarmony (hereinafter referred to as "OpenHarmony"), and learns its design and implementation methods. It contains some tips that can improve the reader's software development skills.
single linked list definition
In OpenHarmony's HDF software module, the singly linked list is defined in hdf_slist.h.
struct HdfSListNode {
struct HdfSListNode *next; // next element in list, or NULL
};
As described in the above figure, each node is a HdfSListNode. There are 5 nodes in the above figure, and each node has a next member, whose value is the address of the next node in memory. Since the next node can be found through this address, the relationship is described by a red right arrow in the figure. On the whole, from the No. 1 node, the next four nodes can be found in turn through the next member. From the graph, it is a logical chain relationship. We call this structure a linked list.
Looking at node 5 alone, node 5 has no next node, so it is necessary to give a specific value to represent it in design. In implementation, the next member of node 5 is generally filled with a value of 0, indicating that it is the last node.
Next we look at the following data structure:
struct HdfSList {
struct HdfSListNode *root;
};
Its schematic diagram is as follows:
As shown in the figure above, the rounded rectangle represents HdfSList, and its root member records the address of a node in the linked list. In order to access the entire linked list, the value of the root member needs to be set to the address of the first node. Because the singly linked list only supports searching in one direction, and does not support searching back, such as the above error example. If root records the address of the second node, the first node becomes inaccessible.
Introduction to Iterators
Iterators are generated with the concept of collections, which means that each element in the collection is accessed in turn, and iterators provide methods to access these elements. For a singly linked list, each node in the linked list is an element, and all nodes form a set. So you can access the elements in the linked list through iterators.
The basic capabilities and operation paradigms that iterators need to provide are:
初始化迭代器
重复判断(集合中还有未被访问的元素)
获取下一个元素的访问方法
读写下一个元素(也可能是删除这个元素)
结束
The above paradigm shows the usage of iterators. Through iterators, traversing elements becomes simple and straightforward (encapsulates the traversal algorithm in iterators), and does not need to consider the details of data structures for each iteration (there are many kinds of data structures, singly linked list is only one of them one).
For the singly linked list described in this article, it encapsulates the following three functions to support the iterative algorithm. These three functions respectively represent the initialization of the iterator object; whether there are any elements in the collection that do not participate in the iteration; take out the next element in the collection that can participate in the iteration.
/* * @brief initialize iterator * * @param[in] iterator the point of iterator. * @param[in] list the point of operation list. * * @return None */
void HdfSListIteratorInit(struct HdfSListIterator *iterator, struct HdfSList *list);
/* * @brief check whether list has next node. * * @param[in] iterator the point of iterator. * * @return the result of check next. */
bool HdfSListIteratorHasNext(struct HdfSListIterator *iterator);
/* * @brief get next link in the list and move iterator to next. * * @param[in] iterator the point of iterator. * * @return point to next element of it. */
struct HdfSListNode *HdfSListIteratorNext(struct HdfSListIterator *iterator);
Iterator Implementation Considerations
For the singly linked list iterator described in this article. Intuitively, except for the first node, other nodes can be accessed through next, and the first node can be accessed through root. Could it actually be that simple? In fact, it is not, because the factor of node deletion needs to be considered. As shown in the figure below, in the process of linked list iteration, if the current node is deleted, how to find the next node?
As shown in the figure above, when the curr node is removed during the traversal, then it is impossible to find the next node through it. So at this time, we must use the previous node on the linked list before operating curr, that is, the prev node in the above figure, through its next member, to find the next node that needs to be iteratively processed. Therefore, the location information of the two nodes, prev and curr, needs to be recorded during the iteration. The iterative process is actually the process of adjusting prev and curr. For the case of not deleting, prev and curr move backwards in turn. When deleting, only curr is moved.
In addition, special processing is required for the case of the first node, so an additional information is required to indicate whether to iterate the first element, because the iterator object described in this article contains 3 pieces of information. As shown in the following code:
struct HdfSListIterator {
int stepOnNext; //是否即将开始遍历第二个以及之后的元素
struct HdfSListNode *prev; // points to the item before the current one 当前被操作元素的前一个元素
struct HdfSListNode *curr; // points to the current item (to detect item removal) 当前被操作的元素,可能刚操作完,被移除链表
};
The functions of prev and curr in the above code have been described in detail above, and stepOnNext means whether the second element has been fetched. That is to separate the fetching algorithm for the first element from the second element.
in conclusion
In embedded development, in learning data structure courses, in the development of OpenHarmony project, singly linked list is very important, and this article is only the implementation of singly linked list of one of the software modules. Through the graphical analysis of the implementation of the singly linked list, especially the analysis of the iterator idioms, I believe that the reader's understanding of the singly linked list and iterators will be further improved. More detailed code analysis and reading are left to the readers themselves, please refer to the following code file:
https://gitee.com/openharmony/drivers_hdf_core/blob/master/framework/utils/include/hdf_slist.h
https://gitee.com/openharmony/drivers_hdf_core/blob/master/framework/utils/src/hdf_slist.c
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。