一个数据结构的问题(第一次发帖,没有分,还是希望大家能帮帮我!)

symnphrost 2009-08-09 11:50:47
我现在建了如下的类:
class info
{
public :
int h;
char status;
info *next_pos;
info *next_h;
info *prior_pos;
info *prior_h;
};
info t[1000];
输入n个数(n<1000)并赋值到h中,现在要求建立以下的双链表:*prior_pos,*next_pos是根据输入顺序建立的链表,*prior_h,*next_h;是根据h的升序建立的链表.
初学,希望大家帮帮忙!
最好能给出代码我可以自己研究,思路我也有,但就是实现不了。还好我开始自学了,不然下学期真得很容易挂科。。。
...全文
211 点赞 收藏 14
写回复
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
呵呵,路过,我学的是C,不过和C++有相似之处吧,算法的实现我现在也不是很会,尤其是数据结构这块算法实现,多找个例子研究研究吧
回复
symnphrost 2009-08-13
[Quote=引用 11 楼 currenttt 的回复:]
引用 9 楼 symnphrost 的回复:
哦,看到你的代码了,谢谢啊~
不过我要处理的是100万的数据,用插入法排序可能太慢了,真的没有办法把复杂度降到nlog(n)吗?

囧,为什么你刚开始学数据结构就要处理百万级的数据量……
[/Quote]

实话跟你招了吧,这是ACM的题目。。。。。输入输出有30M。。。
回复
勤奋的沉沦 2009-08-13

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map>
#include <iostream>
using namespace std;

class info
{
public :
int h;
char status;
info *next_pos;
info *next_h;
info *prior_pos;
info *prior_h;
};



int main(int argc, char *argv[])
{
map<int, info *> m;
FILE *fp;
int i, j, n;
info *inf, *tmp, *h, *pos;
if ((fp = fopen(argv[1], "r")) == NULL) {
return -1;
}
tmp = NULL;
while (!feof(fp) && fscanf(fp, "%d ", &n)) {
inf = new info();
inf->h = n;
inf->prior_pos = tmp;
inf->next_pos = NULL;
inf->prior_h = inf->next_h = NULL;
m.insert(map<int, info *>::value_type(n, inf));
if (tmp) {
tmp->next_pos = inf;
} else {
pos = inf; //保存头节点
}
tmp = inf;
}
fclose(fp);
if (tmp) tmp->next_pos = NULL;
tmp = NULL;
for (map<int, info *>::iterator it = m.begin(); it != m.end(); ++it) {
it->second->next_h = NULL;
it->second->prior_h = tmp;
if (tmp) { tmp->next_h = it->second; }
else h = it->second; //保存头节点
tmp = it->second;
}
tmp->next_h = NULL;
#ifdef _DEBUG_
tmp = h;
while (tmp)
{
printf("%d->", tmp->h);
tmp = tmp->next_h;
}
tmp = pos;
printf("\n");
while (tmp)
{
printf("%d->", tmp->h);
tmp = tmp->next_pos;
}
#endif
return 0;
}



如果数字有重复的 可以把map<int, info *> 换下, 再把比较方法重载下应该可以解决
回复
勤奋的沉沦 2009-08-11
输入的时候建立好输入链表,同时向1个排序树插入节点,输入完后,将排序树先序遍历建立排序链表应该就可以了。
回复
symnphrost 2009-08-11
[Quote=引用 7 楼 currenttt 的回复:]
引用 4 楼 symnphrost 的回复:
我是想这样实现的:
先输入h,同时建好pos的链表,这个简单;
然后调用qsort排序建立h的链表,可是一用qsort原来的链表就被破坏了,不改变顺序的话就不能用qsort。
也想过输入一个插一个,可是2分法还不会用。
所以最好能用qsort。。

你的这个思路是不对的。
    首先你要了解qsort的适用范围,它要求排序的对象在一段连续的内存空间内,其大小由qsort中的两个size_t决定。而链表中各个节点并不是连续存储的,因此无法直接使用qsort
    同理,在你给的这个数据结构的基础上,也无法使用你所说的二分插入法,因为没法确定一个链表的“中间”在哪里,采用插入排序是比较合理的做法。
[/Quote]

哦,看到你的代码了,谢谢啊~
不过我要处理的是100万的数据,用插入法排序可能太慢了,真的没有办法把复杂度降到nlog(n)吗?
回复
currenttt 2009-08-11

#include <iostream>
using namespace std;

class info
{
public :
int h;
char status;
info *next_pos;
info *next_h;
info *prior_pos;
info *prior_h;

info(int val = 0)
{
h = val;
next_pos = next_h = prior_pos = prior_h = NULL;
}
};
//info t[1000]; //构造链表的话,这样的声明就没有意义了

void append(info* head, info**pre, int val)
{
info* n = new info(val);

//根据输入顺序建立链表
(*pre)->next_pos = n;
n->prior_pos = *pre;

//插入排序
info *t = head;
while (t->next_h != NULL)
{
if (t->next_h->h >= val)
{
break;
}
t = t->next_h;
}
n->next_h = t->next_h;
if (t->next_h)
{
t->next_h->prior_h = n;
}
t->next_h = n;
n->prior_h = t;

*pre = n;
}

int init(info **head)
{
*head = new info();
return 0;
}
int destory(info *head)
{
info *t = head->next_pos;
info *del;
while (t)
{
del = t;
t = t->next_pos;
delete []del;
}
head->next_pos = NULL;
return 0;
}

void showList(info *head)
{
//顺序输出
info* t = head;
while (t->next_h)
{
cout << t->next_h->h << ' ';
t = t->next_h;
} cout << endl;

//逆序输出
while (t != head)
{
cout << t->h << ' ';
t = t->prior_h;
} cout << endl;
}

int main()
{
int n;
int val;
info *phead = NULL; //phead是表头,不用于存储数据
info *pins = NULL;

init(&phead);
pins = phead;

cin >> n;
for (int i = 0; i < n; i++)
{
cin >> val;
append(phead, &pins, val);
}

showList(phead);

destory(phead);
system("pause");
return 0;
}
回复
currenttt 2009-08-11
[Quote=引用 9 楼 symnphrost 的回复:]
哦,看到你的代码了,谢谢啊~
不过我要处理的是100万的数据,用插入法排序可能太慢了,真的没有办法把复杂度降到nlog(n)吗?
[/Quote]
囧,为什么你刚开始学数据结构就要处理百万级的数据量……
回复
currenttt 2009-08-10
不知道LZ对于C++的语法和链表的基本操作知悉多少?又是否知道插入排序的算法呢?

LZ的问题是一组输入,两组操作,把LZ的问题分成两个来看会容易一些:
第一个问题:按照输入顺序建立顺序链表
第二个问题:将输入的整型按照其值组织成有序的链表

虽然结构体里是4个指针,但实际上可以看做毫不相关的两组:
第一组:由next_pos和prior_pos构成的链表,按用户的输入顺序组织
第二组:next_h和prior_h,按数值的大小组织(LZ这里的prior应该是pre吧……)
对第一组指针,根据输入顺序建立顺序链表;对第二组指针,每输入一个数,就对其进行插入排序。

回复
请给出你的思路,想想你哪一个地方实现不了。
哪些地方实现得了。

我给的思路
最简单的办法,
就是先用数组存h,
排序。

排好序之后,
只要会建立链表就行了。
回复
LeonTown 2009-08-10
可以先一步一步的来。

先建立链表,通过prior_pos和next_pos。
这个应该简单。

然后,在建立排序的链表。
最多n*n的复杂度。
回复
currenttt 2009-08-10
[Quote=引用 4 楼 symnphrost 的回复:]
我是想这样实现的:
先输入h,同时建好pos的链表,这个简单;
然后调用qsort排序建立h的链表,可是一用qsort原来的链表就被破坏了,不改变顺序的话就不能用qsort。
也想过输入一个插一个,可是2分法还不会用。
所以最好能用qsort。。
[/Quote]
你的这个思路是不对的。
首先你要了解qsort的适用范围,它要求排序的对象在一段连续的内存空间内,其大小由qsort中的两个size_t决定。而链表中各个节点并不是连续存储的,因此无法直接使用qsort
同理,在你给的这个数据结构的基础上,也无法使用你所说的二分插入法,因为没法确定一个链表的“中间”在哪里,采用插入排序是比较合理的做法。
回复
symnphrost 2009-08-10
加了点分,自己顶一下,同时再说明下:
对h的排序有冒泡肯定是不行的,太慢了,最好是能用qsort来排序。
如果是输入一个插入一个的话,也要用2分法的插入。
希望给出完整的实现代码,感激不尽!
回复
symnphrost 2009-08-10
c++才学了一年,链表还没教过,所以暑假里在自学。。
你的思路我懂,可是涉及到链表后插入排序不会实现了。
一开始,我是想这样实现的:
先输入h,同时建好pos的链表,然后调用qsort排序建立h的链表,可是一用qsort原来的链表就被破坏了,不改变顺序的话就不能用qsort。
然后我也想到输入一个插入一个这种方法,可是就是不会实现啊,2分法也只是知道大概的思路。。


[Quote=引用 3 楼 currenttt 的回复:]
不知道LZ对于C++的语法和链表的基本操作知悉多少?又是否知道插入排序的算法呢?

LZ的问题是一组输入,两组操作,把LZ的问题分成两个来看会容易一些:
第一个问题:按照输入顺序建立顺序链表
第二个问题:将输入的整型按照其值组织成有序的链表

虽然结构体里是4个指针,但实际上可以看做毫不相关的两组:
第一组:由next_pos和prior_pos构成的链表,按用户的输入顺序组织
第二组:next_h和prior_h,按数值的大小组织(LZ这里的prior应该是pre吧……)
对第一组指针,根据输入顺序建立顺序链表;对第二组指针,每输入一个数,就对其进行插入排序。


[/Quote]
回复
symnphrost 2009-08-10
我是想这样实现的:
先输入h,同时建好pos的链表,这个简单;
然后调用qsort排序建立h的链表,可是一用qsort原来的链表就被破坏了,不改变顺序的话就不能用qsort。
也想过输入一个插一个,可是2分法还不会用。
所以最好能用qsort。。
[Quote=引用 2 楼 vshuang 的回复:]
请给出你的思路,想想你哪一个地方实现不了。
哪些地方实现得了。

我给的思路
最简单的办法,
就是先用数组存h,
排序。

排好序之后,
只要会建立链表就行了。
[/Quote]
回复
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
社区公告
暂无公告