Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
2 / 2 / 0
Регистрация: 28.05.2015
Сообщений: 19

Реализация хеш-таблицы через список, удаление элемента по ключу

23.11.2019, 22:24. Показов 1733. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
Type Hash = ^PHash;
PHash = record
Data: integer; 
Next:hash;
End;
//Объявление таблицы:
Const m = 11;
type h_table=array [0..m-1] of hash;
var 
i,a: integer;
table: h_table; 
//инициализация
procedure preparation_h_table(var table:h_table); 
var i:integer;
begin
        for i:=0 to m-1 do
             table[i]:=nil;
end;
function hash_func(key:integer) : integer;
begin
        hash_func:=key mod m;
end;
//процедуры добавления в список
procedure addItem_to_Begin(var L:Hash;item:integer);
var Q:Hash;
begin
    new(Q);
    Q^.Data:=item;
    Q^.Next:=L;
    L:=Q;
end;
procedure addItem_to_End(var L:Hash; var T:Hash; item:integer);
var Q:Hash;
begin
        if L=nil then
        begin
                addItem_to_Begin(L,item);
                T:=L;
        end
        else
        begin
            T:=L;
            while T^.next<> nil do T:=T^.next;
            new(Q);
            Q^.Data:=item;
            Q^.Next:=nil;
            T^.Next:=Q;
            T:=Q;
        end;
end;
//добавление в таблицу
procedure add_to_hash(var table:h_table; key:integer);
var i:integer;
var T:hash;
begin
    i:= hash_func (key);
    addItem_to_End(table[i],T,key);
end;
//удаление по ключу
procedure find_Item_by_Key(L:Hash; key:integer; var T:Hash; var TPrev:Hash);
begin
    T:=L;
    while T<> nil do 
    begin
        if T^.Data=key then break;
        TPrev:=T;
        T:=T^.next;
    end;
end;
procedure delete_by_key(var L:Hash; key:integer);
var Q,T,TPrev:Hash;
begin
      find_Item_by_Key(L,key,T,TPrev);
      if TPrev<>nil then writeln ('предыдущий элемент ',TPrev^.Data);
      if TPrev=nil then writeln ('первый элемент');
      writeln ('нужный элемент ',T^.Data);
    if TPrev=nil then 
    begin
     Q:=L; 
     writeln ('нужный первый элемент ',Q^.Data);
     L:=Q^.next;
     writeln ('нужный следующий элемент ',Q^.Data);
    end
    else
    begin
    Q:=TPrev^.next;
      TPrev^.next:=Q^.next;
    end;
    Dispose (Q);
end; 
procedure delete_table_key(table:h_table; key:integer);
var i:integer;
begin
        for i:=0 to m-1 do
        if i=hash_func(key) then delete_by_Key (table[i],key);
end;
//вывод таблицы
procedure write_List(L:Hash);
var Q:Hash;
begin
    Q:=L;
    writeln;
    while Q<>nil do
    begin
        write(Q^.Data,' ');
        Q:=Q^.next;
    end;
end;
procedure write_h_table(table:h_table);
var i:integer;
begin
        for i:=0 to m-1 do
        if   table[i]=nil then 
        begin
          Writeln;
          Write('*');
        end
        else
             write_List(table[i]);
end;
begin
   preparation_h_table(table);
   //16,22,8,14,24,18,5,10,12,2,13,12,12,14,17,11,7,19,23,4,6,15,19,2,7
   for i:=0 to 24 do
   begin
   Readln (a);
   add_to_hash(table, a);
   end;
     write_h_table(table);
     writeln;
     delete_table_key (table,23);
     writeln;
     write_h_table(table);
end.
Собственно реализовал хеш-таблицу через список, только у меня если ключ один и тот же записывается несколько раз, то и создается несколько элементов списка. Как это пофиксить?
Также когда хочу удалить элемент по ключу в delete_table_key(table,key), нормально удаляется не первый элемент списка, а с первым не получается, хотя вроде нормально даю указатель начала списка на следующий элемент (79 и 81 строчки кода). Тоже не знаю как это пофиксить.
Благодарю за любую помощь.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
23.11.2019, 22:24
Ответы с готовыми решениями:

Удаление элемента из хеш таблицы
Не получается удаление.Записано в баттон3 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes,...

Двусвязный список. Удаление элемента по ключу
Привет, товарищи-форумчане. Нужно построить двусвязный список из фамилий. Оставить в нем только фамилии, начинающиеся на букву «А»,...

Реализация хеш-таблицы
Всем привет. Нужна помощь с заданием:

2
 Аватар для Sun Serega
2355 / 1458 / 526
Регистрация: 07.04.2017
Сообщений: 4,798
23.11.2019, 23:54
Цитата Сообщение от Corvinas Посмотреть сообщение
то и создается несколько элементов списка
Так а что не правильно то? Если по ключу есть несколько элементов - их должно выстраивать в связный список. Или что то другое происходит?

Но с кодом в старом стиле и практически без форматирования - желания разбираться нет. Вот нормальный:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
type
  MyHashSetNode<T> = class
    data: T;
    next: MyHashSetNode<T>; // экземляры классов и так хранятся по ссылке (перекрашенному указателю), поэтому засорять код лишними "^" не надо
  end;
  
  MyHashSet<T> = sealed class
    private const root_c = 16; // должно быть степенью двойки, а не 11, иначе будет медленно
    private roots := new MyHashSetNode<T>[root_c];
    
    private static function ContainsIn(n: MyHashSetNode<T>; a: T): boolean;
    begin
      while n<>nil do
      begin
        if n.data=a then
        begin
          Result := True;
          exit;
        end;
        n := n.next;
      end;
    end;
    
    /// Возвращает True если элемент уже содержится
    public function Contains(a: T): boolean;
    begin
      // из за того что root_c степерь двойки - можно применять побитовое and вместо mod, а это быстрее
      var root_id := a.GetHashCode and (root_c-1);
      Result := ContainsIn(roots[root_id], a);
    end;
    
    /// Добавляет элемент, если его ещё нет
    /// Возвращает True если новый элемент был добавлен
    public function Add(a: T): boolean;
    begin
      var root_id := a.GetHashCode and (root_c-1);
      if ContainsIn(roots[root_id], a) then exit;
      
      var nn := new MyHashSetNode<T>;
      nn.data := a;
      nn.next := roots[root_id];
      roots[root_id] := nn;
      
      Result := True;
    end;
    
    /// Удаляет элемент, если он есть
    /// Возвращает True если элемент был удалён
    public function Remove(a: T): boolean;
    begin
      var root_id := a.GetHashCode and (root_c-1);
      
      var n := roots[root_id];
      if n=nil then exit;
      if n.data=a then
      begin
        roots[root_id] := n.next;
        Result := True;
        exit;
      end;
      
      var prev := n;
      n := n.next;
      while n<>nil do
      begin
        
        if n.data=a then
        begin
          prev.next := n.next;
          Result := True;
          exit;
        end;
        
        prev := n;
        n := n.next;
      end;
      
    end;
    
    // вообще для этого лучше реализовать IEnumerable, но для простоты так:
    function EnmrAll: sequence of T;
    begin
//      for var i := 0 to root_c-1 do //ToDo сейчас так не видит root_c, https://github.com/pascalabcnet/pascalabcnet/issues/2152
      for var i := 0 to MyHashSet&<T>.root_c-1 do
      begin
        var n := roots[i];
        
        while n<>nil do
        begin
          yield n.data;
          n := n.next;
        end;
        
      end;
    end;
    
  end;
  
begin
  var hs := new MyHashSet<integer>;
  
  Writeln('Добавление 3 элементов в общий связный список:');
  hs.Add(5).Println;
  hs.Add(5+16).Println;
  hs.Add(5+16*2).Println;
  hs.EnmrAll.Println;
  Writeln;
  
  Writeln('Удаление 2 из них:');
  hs.Remove(5+16).Println;
  hs.Remove(5+16*2).Println;
  hs.Remove(5+16*2).Println; // второй раз уже вернёт False, потому что теперь такого элемента нет
  hs.EnmrAll.Println;
  Writeln;
  
  hs.Contains(5).Println;
  hs.Contains(6).Println;
  
end.
0
2 / 2 / 0
Регистрация: 28.05.2015
Сообщений: 19
24.11.2019, 00:30  [ТС]
Я имею в виду, если у меня длина таблицы 11, это такое требование, то например если я дважды добавляю 12, то должен в списке быть только один 12. И мне надо дополнить мой код, брать чужой мне нет смысла. Если есть вопросы по функциям, я объясню что они должны делать.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
24.11.2019, 00:30
Помогаю со студенческими работами здесь

Реализация хеш-таблицы
Реализовать АТД «хеш-таблица». В АТД должны быть реализованы следующие операции: 1. добавление элемента с заданным ключом; 2. поиск...

Реализация хеш-таблицы
Здравствуйте! В некоторых реализациях хеш-таблицы функция удаления значения выглядит так, что на место значения, которое необходимо...

Реализация Хеш-таблицы
Пытаюсь вникнуть в очередную структуру данных. По идее, при вводе push x y , значение x должно заноситься как ключ, y - как значение. ...

Словари / удаление элемента из списка по ключу
Имеется словарь: a = {1: } Как удалить &quot;two&quot;?

Удаление элемента ассоциативного двумерного массива по известному ключу
Всем привет, есть массив вида: array( array( 'name' =&gt; 'Сидоров', 'specialty' =&gt; 'техник' '), ... array ( 'name' =&gt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США. Нашел на реддите интересную статью под названием «Кто-нибудь знает, где получить бесплатный компьютер или. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru