当我们没有被告知它的大小时如何找到链表的中间部分,并且必须仅使用一个循环和仅一个指针来执行。
答案 0 :(得分:13)
怎么样
LinkedList * llist = getLList(); // the linked list
Node * node = llist.head;
while ( node ) {
node = node.next;
if ( node ) {
node = node.next;
llist.remove( llist.head );
}
}
// now llist.head is (er, um... was) the middle node.
// hope you didn't need the rest of the list.
答案 1 :(得分:8)
Node *m,*e,*head; /* head is given */
m=e=head;
while(e) {
e=e->next;
if (e) {
e=e->next;
m=m->next;
}
}
/* now m is the middle node */
抱歉,我必须使用2个指针:)
将此添加到您的答案中,因为小调整会将指针数量减少到1.我希望您不介意:
Node m,*e,*head; /* head is given */
e = head;
if (e) m = *e;
while(e) {
e = e->next;
if (e) {
e = e->next;
m = *(m.next);
}
}
/* now m is the middle node */
答案 2 :(得分:2)
嗯,这有点像黑客,因为它在功能上等同于2个循环。但是,它只是一个循环。
Node* middle(Node* const begin)
{
Node* current = begin;
bool size_known = false;
int size = 0;
while (true)
{
if (!size_known)
{
if (current)
{
++size;
current = current->next;
}
else
{
current = begin;
size_known = true;
}
}
else
{
if (size <= 1)
return current;
current = current->next;
size -= 2;
}
}
}
答案 3 :(得分:1)
查看我的代码。它正确地在我的FC9 x86_64上工作,函数“middle()”就是你想要的:
static struct node *middle(struct node *head)
{
struct node *mid = head;
int flag = 0;
while (NULL != head) {
head = head->next;
flag = !flag;
if (flag) {
mid = mid->next;
}
}
return mid;
}
编辑:删除除中间()之外的代码。
答案 4 :(得分:1)
在这种情况下我们可以使用跳过列表:
1)遍历链接列表中的每个节点时,会生成奇数节点的跳过列表。时间:O(n)空间:O(n / 2)
2)现在当你到达列表的末尾时,将legnth除以2并加1以获得中间元素索引。
3)在跳过列表O(登录)时间内搜索索引。
因此,算法的整体时间复杂度将是:
O(n)(1遍历)+ O(logn)(搜索跳过列表)= O(n) 空间复杂度:O(n / 2)
请回复这是否效率低......
答案 5 :(得分:0)
使用提供的头指针迭代你的列表,并递增你的一个允许指针(我假设你的一个含糊不清的问题,你允许一个指针除了传入的那个)一次对于头指针的每两个增量。
Node* middle( Node* head )
{
Node* middle = head;
while (head != NULL) {
head = head->next;
if (head->next != NULL) {
head = head->next;
middle = middle->next;
}
}
return middle;
}
这里忽略了边缘情况(就像具有偶数元素的列表的中间部分一样)。
答案 6 :(得分:-1)
自已标记c ++以来,C ++查找列表中间位置的方法:
#include <list>
using namespace std;
using IntegerList = list<int>;
int main() {
IntegerList l;
for (int i : {0, 1, 2, 3, 4, 5, 6})
l.push_back(i * 1);
auto m = l.begin();
bool even = false;
for(auto &z:l) {
if (even) ++m;
even = !even;
}
cout << "\nmiddle of the list:" << *m << "\n";
}