在c中对双向链表进行排序(Sorting doubly linked list in c)
我想在插入元素时按排序顺序保留链表(列表中大约200000个元素),您可以推荐哪种算法? 我使用插入排序做了一个简单的实现,但它的性能非常糟糕(很多CPU使用率)。
谢谢你的帮助。
我在合并排序和插入排序之间进行了一些比较,但似乎插入排序具有更好的性能,我对这个结果有点困惑。 你能告诉我什么是错的,是否有更好的算法?
我的代码(为简单起见,我省略了节点结构中的prev节点):
struct node { int number; struct node *next; };
插入排序:
void insert_node(int value) { struct node *new_node = NULL; struct node *cur_node = NULL; struct node *last_node = NULL; int found; /* 1 means found a place to insert the new node in, 0 means not*/ new_node = (struct node *)malloc(sizeof(struct node *)); if(new_node == NULL) { printf("memory problem\n"); } new_node->number = value; /* If the first element */ if (head == NULL) { new_node->next = NULL; head = new_node; } else if (new_node->number < head->number) { new_node->next = head; head = new_node; } else { cur_node = head; found = 0; while (( cur_node != NULL ) && ( found == 0 )) { if( new_node->number < cur_node->number ) { found = 1; } else { last_node = cur_node; cur_node = cur_node->next; } } /* We got the right place to insert our node */ if( found == 1 ) { new_node->next = cur_node; } /* Insert at the tail of the list */ else { last_node->next = new_node; new_node->next = NULL; } }
合并排序:
/* add a node to the linked list */ struct node *addnode(int number, struct node *next) { struct node *tnode; tnode = (struct node*)malloc(sizeof(*tnode)); if(tnode != NULL) { tnode->number = number; tnode->next = next; } return tnode; } /* perform merge sort on the linked list */ struct node *merge_sort(struct node *head) { struct node *head_one; struct node *head_two; if((head == NULL) || (head->next == NULL)) return head; head_one = head; head_two = head->next; while((head_two != NULL) && (head_two->next != NULL)) { head = head->next; head_two = head->next->next; } head_two = head->next; head->next = NULL; return merge(merge_sort(head_one), merge_sort(head_two)); } /* merge the lists.. */ struct node *merge(struct node *head_one, struct node *head_two) { struct node *head_three; if(head_one == NULL) return head_two; if(head_two == NULL) return head_one; if(head_one->number < head_two->number) { head_three = head_one; head_three->next = merge(head_one->next, head_two); } else { head_three = head_two; head_three->next = merge(head_one, head_two->next); } return head_three; }
I want to keep a linked list in sorted order when inserting elements (about 200000 elements in the list), which algorithm can you recommend? I made a simple implementation using insertion sort, but its performance is very very bad (a lot of CPU usage).
Thanks for your help.
I did some comparison between merge sort and insertion sort but it seems that insertion sort has better performance, I am a bit confused by this result. Can you tell me what's wrong and if there is a better algorithm?
My code (for simplicity, I omitted the prev node in the node struct):
struct node { int number; struct node *next; };
Insertion sort :
void insert_node(int value) { struct node *new_node = NULL; struct node *cur_node = NULL; struct node *last_node = NULL; int found; /* 1 means found a place to insert the new node in, 0 means not*/ new_node = (struct node *)malloc(sizeof(struct node *)); if(new_node == NULL) { printf("memory problem\n"); } new_node->number = value; /* If the first element */ if (head == NULL) { new_node->next = NULL; head = new_node; } else if (new_node->number < head->number) { new_node->next = head; head = new_node; } else { cur_node = head; found = 0; while (( cur_node != NULL ) && ( found == 0 )) { if( new_node->number < cur_node->number ) { found = 1; } else { last_node = cur_node; cur_node = cur_node->next; } } /* We got the right place to insert our node */ if( found == 1 ) { new_node->next = cur_node; } /* Insert at the tail of the list */ else { last_node->next = new_node; new_node->next = NULL; } }
Merge Sort :
/* add a node to the linked list */ struct node *addnode(int number, struct node *next) { struct node *tnode; tnode = (struct node*)malloc(sizeof(*tnode)); if(tnode != NULL) { tnode->number = number; tnode->next = next; } return tnode; } /* perform merge sort on the linked list */ struct node *merge_sort(struct node *head) { struct node *head_one; struct node *head_two; if((head == NULL) || (head->next == NULL)) return head; head_one = head; head_two = head->next; while((head_two != NULL) && (head_two->next != NULL)) { head = head->next; head_two = head->next->next; } head_two = head->next; head->next = NULL; return merge(merge_sort(head_one), merge_sort(head_two)); } /* merge the lists.. */ struct node *merge(struct node *head_one, struct node *head_two) { struct node *head_three; if(head_one == NULL) return head_two; if(head_two == NULL) return head_one; if(head_one->number < head_two->number) { head_three = head_one; head_three->next = merge(head_one->next, head_two); } else { head_three = head_two; head_three->next = merge(head_one, head_two->next); } return head_three; }
原文:https://stackoverflow.com/questions/9302726
最满意答案
它可能是ListAdapter getView中的一个错误。 你回收列表对象/项目了吗? 回收时,颜色的属性等将保留在对象上。 确保根据任务所处的状态设置属性是否正确。
在getView函数中,您可能检查是否已设置了view-item allready,然后您只需更改项目上任务的文本(回收)? 在代码中的相同位置将背景的颜色设置更改为正确的任务状态。
编辑现在,我看到你的代码看起来你已经混淆了优先级,默认和优先级低将背景设置为prio.setImageResource(R.drawable.fmn_priority_medium); 和medium将背景设置为prio.setImageResource(R.drawable.fmn_priority_low);
好的,我发现了问题:
if((completed.size() != 0) && (completed.contains(task.getText()))) { task.setTextColor(Color.rgb(155, 175, 155)); }
如果未完成,您需要在此处使用else语句将文本颜色设置为原始颜色。 喜欢:
if((completed.size() != 0) && (completed.contains(task.getText()))) { task.setTextColor(Color.rgb(155, 175, 155)); } else { task.setTextColor(Color.rgb(0, 0, 0)); }
It is probably a bug in your ListAdapter getView. Do you recycle your list objects/items? The properties for colors and so on will remain on the object when recycled. Make sure you set the properties correct depending on in which state the task is in.
In the getView function you probably check if the view-item allready is set and then you just change the text for the task on the item (recycling)? At the same place in the code change the color settings for background to the correct task state.
EDIT Now that I see your code it looks like you have got the priorities mixed up, default and priority low set the background to prio.setImageResource(R.drawable.fmn_priority_medium); and medium sets the background to prio.setImageResource(R.drawable.fmn_priority_low);
Ok I found the problem:
if((completed.size() != 0) && (completed.contains(task.getText()))) { task.setTextColor(Color.rgb(155, 175, 155)); }
You need an else statement here to set the text color to the original color if it is not completed. Like:
if((completed.size() != 0) && (completed.contains(task.getText()))) { task.setTextColor(Color.rgb(155, 175, 155)); } else { task.setTextColor(Color.rgb(0, 0, 0)); }
相关问答
更多-
ScrollView中的ListView在Android上不滚动(ListView inside ScrollView is not scrolling on Android)[2022-06-29]
您不应该将ListView放在ScrollView因为ListView类实现了自己的滚动,并且它不会接收手势,因为它们都由父ScrollView处理。 我强烈建议您以某种方式简化布局。 例如,您可以添加要滚动到ListView作为页眉或页脚的视图。 更新 : 从API Level 21(Lollipop)嵌套滚动容器开始,由Android SDK正式支持。 View和ViewGroup类中有一些方法可以提供此功能。 要使Lollipop上的嵌套滚动工作,您必须通过向其XML声明添加android:neste ... -
在另一个可滚动视图中包含可滚动视图通常不是一个好习惯,在这种情况下,直接的方法是向listView添加一个标题。 简单,轻松,性能更佳。 ListView listView = (ListView) findViewById(R.id.list); View header = getLayoutInflater().inflate(R.layout.header, null); listView.addHeaderView(header); 如果您有任何疑问,可以查看本教程 ! (标题将是与您的图像一起的 ...
-
将ListView高度设置为"match_parent" 。 All Right. Solved this. The ListView on the MainActivity was taking all the input touches since i did not specify a gravity for that. Once i added android:layout_gravity="start" to the MainActivity ListView, i was able to sc ...
-
它可能是ListAdapter getView中的一个错误。 你回收列表对象/项目了吗? 回收时,颜色的属性等将保留在对象上。 确保根据任务所处的状态设置属性是否正确。 在getView函数中,您可能检查是否已设置了view-item allready,然后您只需更改项目上任务的文本(回收)? 在代码中的相同位置将背景的颜色设置更改为正确的任务状态。 编辑现在,我看到你的代码看起来你已经混淆了优先级,默认和优先级低将背景设置为prio.setImageResource(R.drawable.fmn_prio ...
-
Android-Listview项目滚动时背景颜色发生变化(Android-Listview items background color changing when scrolling)[2021-03-18]
尝试这个 @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ViewHolder holder; if(convertView==null) { holder = new ViewHolder(); ... -
Android:如何让listview填充其父级而不滚动?(Android: how to make a listview fill its parent without scrolling?)[2022-11-30]
ListView的主要目的之一是在滚动时启用单元格的回收。 如果您希望所有单元格都存在,那么您不需要ListView。 只需使用垂直方向的LinearLayout。 One of the main purposes of a ListView is to enable recycling of cells while scrolling. If you want all the cells to exist, then you don't need a ListView. Just use a vertic ... -
ListView适配器: Animation scaleUp; public MyAdapter(...) { //... scaleUp = AnimationUtils.loadAnimation(activity, R.anim.scale_up_fast); } public View getView(final int position, View convertView, ViewGroup parent) { CardView cv; ...
-
在列表视图,Android中滚动或添加项目时按钮文本消失(button text disappears when scrolling or adding and item in listview, Android)[2023-02-19]
我提到了@Suhas Bachewar的说法,并将代码与代码放在一起,因为您应该知道您正在使用回收程序来让您的视图在列表中填充不同的对象,为什么不在getView中使用点击事件?你不必为了寻找哪个特定的按钮视图与一个必须增加其值的对象相关联而喧嚣, public View getView(int position, View convertView, ViewGroup parentView){ ViewHolder viewHolder; if(convertView == null){ ... -
问题是当convertView == null时你没有把数据放到视图中,你只设置了如何找到它们。 你需要做的是从“else”部分删除实际更改视图的代码,并将其放在整个if-else区域之后。 例子: @Override public View getView(final int position, View convertView, ViewGroup parent) { if (convertView == null) { ... } else view ...
-
问题在于你的布局xml 用这个改变它:
相关文章
更多- hibernate 对list修改
- FreeMarker集合(List、Map)
- Python 列表(list)操作
- Map、List集合类的清空使用clear还是重新new呢
- java List排序一
- wish list: 考虑使用nutch给自己的博客做一个全文检索
- A Great List of Windows Tools
- List用完后需要赋null吗
- el表达式判断list集合是否为空
- JSTL详解之c:forEach
最新问答
更多- 获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)
- 如何通过引用返回对象?(How is returning an object by reference possible?)
- 矩阵如何存储在内存中?(How are matrices stored in memory?)
- 每个请求的Java新会话?(Java New Session For Each Request?)
- css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)
- 无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)
- xcode语法颜色编码解释?(xcode syntax color coding explained?)
- 在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)
- 从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)
- 从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))
- 西安哪有PLC可控制编程的培训
- 在Entity Framework中选择基类(Select base class in Entity Framework)
- 在Android中出现错误“数据集和渲染器应该不为null,并且应该具有相同数量的系列”(Error “Dataset and renderer should be not null and should have the same number of series” in Android)
- 电脑二级VF有什么用
- Datamapper Ruby如何添加Hook方法(Datamapper Ruby How to add Hook Method)
- 金华英语角.
- 手机软件如何制作
- 用于Android webview中图像保存的上下文菜单(Context Menu for Image Saving in an Android webview)
- 注意:未定义的偏移量:PHP(Notice: Undefined offset: PHP)
- 如何读R中的大数据集[复制](How to read large dataset in R [duplicate])
- Unity 5 Heighmap与地形宽度/地形长度的分辨率关系?(Unity 5 Heighmap Resolution relationship to terrain width / terrain length?)
- 如何通知PipedOutputStream线程写入最后一个字节的PipedInputStream线程?(How to notify PipedInputStream thread that PipedOutputStream thread has written last byte?)
- python的访问器方法有哪些
- DeviceNetworkInformation:哪个是哪个?(DeviceNetworkInformation: Which is which?)
- 在Ruby中对组合进行排序(Sorting a combination in Ruby)
- 网站开发的流程?
- 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
- 条带格式类型格式模式编号无法正常工作(Stripes format type format pattern number not working properly)
- 透明度错误IE11(Transparency bug IE11)
- linux的基本操作命令。。。