数据是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并能被计算机程序处理的符号的总称。
数据结构 是指相互之间存在一种或多种特定关系的数据元素的集合。数据结构=数据元素+关系(结构)。
通常有四类基本数据结构:
1.集合(Set)
2.线性结构(Linear Structure)
3.树形结构(Tree Structure)
4.图状结构(Graphic Structure)
数据结构 包括数据的逻辑结构和数据的物理结构
数据的逻辑结构是指送具体的模型抽象出来的数学模型,与数据在计算机中的存储没有关系。
数据的物理结构又称为数据的存储结构 是数据咋计算机中的表示和存储,包括数据元素的表示和存储以及数据元素之间关系的表示和存储。
数据的存储结构包括 顺序存储结构和链式存储结构
算法的时间复杂度:该算法的运行时间和问题规模的对应关系。T(n)=O( f(n) ).
算法的空间复杂度:该算法在运行过程中临时占用的存储空间的大小。
如果一个算法直接调用自己或间接调用自己,就称这个算法是递归的。
线性结构
线性结构的特点结构中的数据元素存在一对一的对应关系。
线性表(List)
是由n(n>=0)个相同类型的数据元素构成的有限序列。
顺序表(Sequence List)
是指用一组地址连续的存储单元依次存储线性表的数据元素。
逻辑上相邻的数据元素物理上也相邻。
链表(Linked List)
链表是用一组任意的存储单元来存储线性表中的数据元素。
链表在存储数据元素时,除了存储元素本身的信息外,还要存储与他相邻的数据元素的存储地址信息。这两部分组成该元素的存储映像,称为结点(Node).把存储数据元素本身信息的域称为结点的数据域,把存储与他相邻的数据元素的存储地址信息的域称为引用域。线性表通过结点的引用域形成一根链条。如果结点的引用域中只存储该结点直接后继的存储地址,则该链表称为单链表(Singly Linked List).把引用域称为next. |data |next|
如果在结点中设两个引用域,一个保存直接前驱的存储地址 prev ,一个保存直接后继的存储地址 next 这种链表就是双向链表(doubly Linked List). |prev|data|next|
循环链表是单链表的一种形式,其最后一个结点的指针不在是空,而是指向头结点,整个链表形成一个环。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace DataStructure 7 { 8 9 public interface ILinarList<T> 10 { 11 void InsertNode(T a, int i); //插入操作 12 void DeleteNode(int i); //删除操作 13 T SearchNode(int i); //查找元素 14 T SearchNode(T value); //定位元素 15 int GetLength(); //求表长度 16 void Clear(); //清空操作 17 bool IsEmpty(); //判断线性表是否为空 18 //bool IsFull(); //判断线性表是否已满 19 } 20 21 /// <summary> 22 /// 顺序表 23 /// </summary> 24 /// <typeparam name="T"></typeparam> 25 public class SeqList<T> : ILinarList<T> 26 { 27 private int maxsize; //顺序表的最大容量 28 private T[] data; 29 private int length; //顺序表的实际长度 30 31 public int Length 32 { 33 get { return length; } 34 } 35 36 public int Maxsize 37 { 38 get { return maxsize; } 39 set { maxsize = value; } 40 } 41 42 public T this[int index] 43 { 44 get { return data[index]; } 45 set { data[index] = value; } 46 } 47 48 public SeqList(int size) 49 { 50 maxsize = size; 51 data = new T[size]; 52 length = 0; 53 } 54 55 56 public void Clear() 57 { 58 length = 0; 59 } 60 61 public bool IsEmpty() 62 { 63 if (length == 0) 64 { 65 return true; 66 } 67 else 68 { 69 return false; 70 } 71 } 72 73 public int GetLength() 74 { 75 return length; 76 } 77 78 public bool IsFull() 79 { 80 if (length == maxsize) 81 { 82 return true; 83 } 84 else 85 { 86 return false; 87 } 88 } 89 90 public void InsertNode(T a) 91 { 92 if (IsFull()) 93 { 94 Console.WriteLine("List is Full !"); 95 return; 96 } 97 data[length] = a; 98 length++; 99 } 100 101 //在第i个数据元素的位置插入一个数据 102 public void InsertNode(T a, int i) 103 { 104 if (IsFull()) 105 { 106 Console.WriteLine("List is Full !"); 107 return; 108 } 109 if (i < 1 || i > length + 1) 110 { 111 Console.WriteLine("Postion is Error !"); 112 return; 113 } 114 else 115 { 116 for (int j = length - 1; j >= i - 1; j--) 117 { 118 data[j + 1] = data[j]; 119 } 120 data[i - 1] = a; 121 } 122 length++; 123 } 124 125 public void DeleteNode(int i) 126 { 127 if (IsEmpty()) 128 { 129 Console.WriteLine("List is Empty !"); 130 return; 131 } 132 if (i < 1 || i > length) 133 { 134 Console.WriteLine("Postion is Error !"); 135 return; 136 } 137 for (int j = i; j < length; j++) 138 { 139 data[j - 1] = data[j]; 140 } 141 length--; 142 } 143 144 public T SearchNode(int i) 145 { 146 if (IsEmpty() || i < 1 || i > length) 147 { 148 Console.WriteLine("List is Empty or Postion is Error !"); 149 return default(T); 150 } 151 return data[i - 1]; 152 } 153 154 public T SearchNode(T value) 155 { 156 if (IsEmpty()) 157 { 158 Console.WriteLine("List is Empty !"); 159 return default(T); 160 } 161 int i = 0; 162 for (i = 0; i < length; i++) 163 { 164 if (data[i].ToString().Contains(value.ToString())) 165 { 166 break; 167 } 168 } 169 if (i >= length) 170 return default(T); 171 return data[i]; 172 } 173 } 174 175 /// <summary> 176 /// 自定义类型 177 /// </summary> 178 class StuNode 179 { 180 private string stu_no; 181 private string stu_name; 182 private int stu_score; 183 184 public string Stu_no 185 { 186 get { return stu_no; } 187 set { stu_no = value; } 188 } 189 190 public string Stu_name 191 { 192 get { return stu_name; } 193 set { stu_name = value; } 194 } 195 196 public int Stu_score 197 { 198 get { return stu_score; } 199 set { stu_score = value; } 200 } 201 202 public StuNode(string stu_no, string stu_name, int stu_score) 203 { 204 this.stu_no = stu_no; 205 this.stu_name = stu_name; 206 this.stu_score = stu_score; 207 } 208 209 public override string ToString() 210 { 211 return stu_no + stu_name; 212 } 213 } 214 215 /// <summary> 216 /// 单链表结点类 217 /// </summary> 218 /// <typeparam name="T"></typeparam> 219 class SNode<T> 220 { 221 private T data; //数据域 222 private SNode<T> next; //应用域 223 224 public SNode(T val, SNode<T> p) 225 { 226 data = val; 227 next = p; 228 } 229 230 public SNode(SNode<T> p) 231 { 232 next = p; 233 } 234 235 public SNode(T val) 236 { 237 data = val; 238 next = null; 239 } 240 241 public SNode() 242 { 243 data = default(T); 244 next = null; 245 } 246 247 //数据域属性 248 public T Data 249 { 250 get { return data; } 251 set { data = value; } 252 } 253 254 //引用域属性 255 public SNode<T> Next 256 { 257 get { return next; } 258 set { next = value; } 259 } 260 261 262 } 263 264 /// <summary> 265 /// 单链表 266 /// </summary> 267 /// <typeparam name="T"></typeparam> 268 class SLinkList<T> : ILinarList<T> 269 { 270 private SNode<T> start; //单链表的头引用 271 int length; //单链表的长度 272 273 public SLinkList() 274 { 275 start = null; 276 } 277 278 //在单链表末尾追加数据元素 279 public void InsertNode(T a) 280 { 281 if (start == null) 282 { 283 start = new SNode<T>(a); 284 return; 285 } 286 SNode<T> current = start;//使current指向第一个结点 287 288 while (current.Next != null) 289 { 290 //找到链表中最后一个结点(从start一直扫描到最后(即next=null)) 291 current = current.Next; 292 } 293 //使current的next字段指向新结点 294 current.Next = new SNode<T>(a); 295 length++; 296 } 297 298 //在单链表的第i个数据元素的位置前插入一个数据元素 299 public void InsertNode(T val, int i) 300 { 301 SNode<T> current; 302 SNode<T> previous; 303 304 if (i < 1) 305 { 306 Console.WriteLine("Postion is Error !"); 307 return; 308 } 309 SNode<T> newnode = new SNode<T>(val); 310 //在空链表或第一个元素前插入第一个元素 311 if (i == 1) 312 { 313 newnode.Next = start; 314 start = newnode; 315 length++; 316 return; 317 } 318 //单链表的两个元素间插入一个元素 319 //使current指向第一个结点 320 current = start; 321 previous = null; 322 323 int j = 1; 324 while (current != null && j < i) 325 { 326 //使previous指向curent 327 previous = current; 328 //使current指向序列中的下一个结点 329 current = current.Next; 330 j++; 331 } 332 if (j == i) 333 { 334 previous.Next = newnode; 335 newnode.Next = current; 336 length++; 337 } 338 } 339 340 public int GetLength() 341 { 342 return length; 343 } 344 345 public void Clear() 346 { 347 //单链表清空后,原结点占有的空间不会一直保留 由垃圾回收器回收 348 start = null; 349 } 350 351 public bool IsEmpty() 352 { 353 if (start == null) 354 { 355 return true; 356 } 357 else 358 { 359 return false; 360 } 361 } 362 363 //删除单链表的第i个元素 364 public void DeleteNode(int i) 365 { 366 if (IsEmpty() || i < 1) 367 { 368 Console.WriteLine("Link is Empty or Positon is Error !"); 369 return; 370 } 371 SNode<T> current = start; 372 if (i == 1) 373 { 374 start = current.Next;//使用current指向单链表中的下一个结点 375 length--; 376 return; 377 } 378 SNode<T> previous = null; 379 int j = 1; 380 while (current.Next != null && j < i) 381 { 382 previous = current; 383 current = current.Next; 384 j++; 385 } 386 if (j == i) 387 { 388 previous.Next = current.Next; 389 current = null; 390 length--; 391 } 392 else 393 { 394 Console.WriteLine("The {0}th node is no exsit !", i); 395 } 396 } 397 398 //获得单链表的第i个数据元素 399 public T SearchNode(int i) 400 { 401 if (IsEmpty()) 402 { 403 Console.WriteLine("Link is Empty !"); 404 return default(T); 405 } 406 SNode<T> current = start; 407 int j = 1; 408 409 while (current.Next != null && j < i) 410 { 411 current = current.Next;//使current指向序列中的下一个结点 直到i 412 j++; 413 } 414 if (j == i) 415 { 416 return current.Data; 417 } 418 else 419 { 420 Console.WriteLine("The {0}th node is no exsit !", i); 421 return default(T); 422 } 423 } 424 425 //在单链表中查找值为value的数据 426 public T SearchNode(T value) 427 { 428 if (IsEmpty()) 429 { 430 Console.WriteLine("List is Empty !"); 431 return default(T); 432 } 433 SNode<T> current = start; 434 int i = 0; 435 while (!current.Data.ToString().Contains(value.ToString()) && current != null) 436 { 437 current = current.Next; 438 i++; 439 } 440 if (current != null) 441 { 442 return current.Data; 443 } 444 else 445 { 446 return default(T); 447 } 448 } 449 450 } 451 452 /// <summary> 453 /// 双向链表结点类 454 /// </summary> 455 /// <typeparam name="T"></typeparam> 456 class DbNode<T> 457 { 458 private T data; //数据域 459 private DbNode<T> prev; //前驱引用域 460 private DbNode<T> next; //后继引用域 461 462 public DbNode(T val, DbNode<T> p) 463 { 464 data = val; 465 next = p; 466 } 467 468 public DbNode(T val) 469 { 470 data = val; 471 next = null; 472 } 473 474 public DbNode() 475 { 476 data = default(T); 477 next = null; 478 } 479 480 public DbNode(DbNode<T> p) 481 { 482 next = p; 483 } 484 485 //数据域属性 486 public T Data 487 { 488 get { return data; } 489 set { data = value; } 490 } 491 492 //前驱引用域属性 493 public DbNode<T> Prev 494 { 495 get { return prev; } 496 set { prev = value; } 497 } 498 499 //后继应用域属性 500 public DbNode<T> Next 501 { 502 get { return next; } 503 set { next = value; } 504 } 505 506 } 507 508 /// <summary> 509 /// 双向链表 510 /// </summary> 511 /// <typeparam name="T"></typeparam> 512 class DlinkList<T> : ILinarList<T> 513 { 514 private DbNode<T> start; //双向列表的头引用 515 private int length; //双链表的长度 516 517 public DlinkList() 518 { 519 start = null; 520 } 521 522 523 public int GetLength() 524 { 525 return length; 526 } 527 528 public void Clear() 529 { 530 start = null; 531 } 532 533 public bool IsEmpty() 534 { 535 if (start == null) 536 return true; 537 else 538 return false; 539 } 540 541 //向双链表的末尾追加数据元素 542 public void InsertNode(T a) 543 { 544 DbNode<T> newNode = new DbNode<T>(a); 545 if (IsEmpty()) 546 { 547 start = newNode; 548 length++; 549 return; 550 } 551 DbNode<T> current = start; 552 553 while (current.Next != null) 554 { 555 current = current.Next; 556 } 557 558 current.Next = newNode; 559 newNode.Prev = current; 560 newNode.Next = null; 561 length++; 562 } 563 564 //在双向链表的第i个数据元素的位置前插入一个数据元素 565 public void InsertNode(T a, int i) 566 { 567 DbNode<T> current; 568 DbNode<T> previous; 569 570 if (i < 1) 571 { 572 Console.WriteLine("Postion is Error !"); 573 return; 574 } 575 576 DbNode<T> newnode = new DbNode<T>(a); 577 578 if (i == 1) 579 { 580 newnode.Next = start; 581 start = newnode; 582 length++; 583 return; 584 } 585 586 //在双向链表的两个元素间插入一个元素 587 current = start; 588 previous = null; 589 int j = 1; 590 591 while (current != null && j < i) 592 { 593 previous = current; 594 current = current.Next; 595 j++; 596 } 597 if (j == i) 598 { 599 newnode.Next = current; 600 newnode.Prev = previous; 601 if (current !=null ) 602 current.Prev = newnode; ; 603 previous.Next = newnode; 604 length++; 605 606 } 607 } 608 609 //删除双向链表的第i个数据元素 610 public void DeleteNode(int i) 611 { 612 if (IsEmpty() || i < 1) 613 { 614 Console.WriteLine("Link is Empty or Postion is Error !"); 615 return; 616 } 617 DbNode<T> current = start; 618 619 if (i == 1) 620 { 621 start = current.Next; 622 length--; 623 return; 624 } 625 626 DbNode<T> previous = null; 627 int j = 1; 628 while (current.Next != null && j < i) 629 { 630 previous = current; 631 current = current.Next; 632 j++; 633 } 634 if (j == i) 635 { 636 previous.Next = current.Next; 637 if (current.Next != null) 638 current.Next.Prev = previous; 639 previous = null; 640 current = null; 641 length--; 642 } 643 else 644 { 645 Console.WriteLine("The {0}th node is not exist !"); 646 } 647 } 648 649 //获得双向链表的第i个元素 650 public T SearchNode(int i) 651 { 652 if (IsEmpty()) 653 { 654 Console.WriteLine("List is Empty !"); 655 return default(T); 656 } 657 DbNode<T> current = start; 658 int j = 1; 659 while (current.Next != null && j < i) 660 { 661 current = current.Next; 662 j++; 663 } 664 if (j == i) 665 { 666 return current.Data; 667 } 668 else 669 { 670 Console.WriteLine("The {0}th node is not exist !"); 671 return default(T); 672 } 673 } 674 675 //在双向链表中查找值为value的数据元素 676 public T SearchNode(T value) 677 { 678 if (IsEmpty()) 679 { 680 Console.WriteLine("List is Empty !"); 681 return default(T); 682 } 683 DbNode<T> current = start; 684 685 int i = 1; 686 while (!current.Data.ToString().Contains(value.ToString()) && current != null) 687 { 688 current = current.Next; 689 i++; 690 } 691 if (current != null) 692 return current.Data; 693 else 694 { 695 return default(T); 696 } 697 } 698 } 699 700 class SeqListApp 701 { 702 static void Main(string[] args) 703 { 704 ILinarList<StuNode> stuList = null; 705 Console.WriteLine("请选择存储结构的类型:1.顺序表 2.单链表 3.双链表 4.循环列表 :"); 706 char selectFlag = Convert.ToChar(Console.ReadLine()); 707 switch (selectFlag) 708 { 709 case '1': 710 Console.WriteLine("请输入学生数:"); 711 int maxsize = Convert.ToInt32(Console.ReadLine()); 712 stuList = new SeqList<StuNode>(maxsize); 713 break; 714 case '2': 715 stuList = new SLinkList<StuNode>(); 716 break; 717 case '3': 718 stuList = new DlinkList<StuNode>(); 719 break; 720 default: 721 break; 722 } 723 while (true) 724 { 725 Console.WriteLine("请输入操作选项:"); 726 Console.WriteLine("1.添加学生成绩"); 727 Console.WriteLine("2.删除学生成绩"); 728 Console.WriteLine("3.按姓名查询学生成绩"); 729 Console.WriteLine("4.按学号查询学生成绩"); 730 Console.WriteLine("5.按升序显示所有的学生成绩"); 731 Console.WriteLine("6.按降序显示所有的学生成绩"); 732 Console.WriteLine("7.退出"); 733 selectFlag = Convert.ToChar(Console.ReadLine()); 734 735 switch (selectFlag) 736 { 737 /*添加学生信息*/ 738 case '1': 739 { 740 char flag; 741 do 742 { 743 string stu_no; 744 string stu_name; 745 int stu_score; 746 747 Console.WriteLine("请输入学号:"); 748 stu_no = Console.ReadLine(); 749 Console.WriteLine("请输入学生姓名:"); 750 stu_name = Console.ReadLine(); 751 752 Console.WriteLine("请输入学生成绩:"); 753 stu_score = Convert.ToInt32(Console.ReadLine()); 754 755 StuNode newNode = new StuNode(stu_no, stu_name, stu_score); 756 if (stuList.GetLength() == 0) 757 { 758 stuList.InsertNode(newNode, 1); 759 } 760 else if (newNode.Stu_score > stuList.SearchNode(stuList.GetLength()).Stu_score) 761 { 762 stuList.InsertNode(newNode, stuList.GetLength() + 1); 763 } 764 else 765 { 766 for (int i = 1; i < stuList.GetLength(); i++) 767 { 768 if (newNode.Stu_score <= stuList.SearchNode(i).Stu_score) 769 { 770 stuList.InsertNode(newNode, i); 771 break; 772 } 773 } 774 } 775 Console.WriteLine("继续输入学生信息?(Y/N)"); 776 flag = Convert.ToChar(Console.ReadLine()); 777 } while (flag == 'Y'); 778 break; 779 } 780 /*按学号删除学生信息*/ 781 case '2': 782 { 783 StuNode temp; 784 Console.WriteLine("请输入要删除的学生学号:"); 785 string stu_no = Console.ReadLine(); 786 for (int i = 1; i < stuList.GetLength(); i++) 787 { 788 temp = stuList.SearchNode(i); 789 if (temp.Stu_no == stu_no) 790 { 791 stuList.DeleteNode(i); 792 break; 793 } 794 } 795 break; 796 } 797 /*按姓名查询学生信息*/ 798 case '3': 799 { 800 StuNode temp; 801 Console.WriteLine("请输入要查询的学生姓名:"); 802 string stu_name = Console.ReadLine(); 803 for (int i = 1; i <= stuList.GetLength(); i++) 804 { 805 temp = stuList.SearchNode(i); 806 if (temp.Stu_name == stu_name) 807 { 808 Console.WriteLine("{0}的成绩是:{1}", stu_name, temp.Stu_score); 809 break; 810 } 811 } 812 break; 813 } 814 /*按学号查询学生信息*/ 815 case '4': 816 { 817 StuNode temp; 818 Console.WriteLine("请输入要查询的学生学号:"); 819 string stu_no = Console.ReadLine(); 820 for (int i = 1; i <= stuList.GetLength(); i++) 821 { 822 temp = stuList.SearchNode(i); 823 if (temp.Stu_no == stu_no) 824 { 825 Console.WriteLine("学号为{0}的学生的成绩是:{1}", stu_no, temp.Stu_score); 826 break; 827 } 828 } 829 break; 830 } 831 /*按升序显示所有学生的成绩*/ 832 case '5': 833 { 834 StuNode temp = null; 835 for (int i = 1; i <= stuList.GetLength(); i++) 836 { 837 temp = stuList.SearchNode(i); 838 Console.WriteLine(" {0}\t{1}\t{2}", temp.Stu_no, temp.Stu_name, temp.Stu_score); 839 } 840 break; 841 } 842 case '6': 843 { 844 StuNode temp = null; 845 for (int i = stuList.GetLength(); i >= 1; i--) 846 { 847 temp = stuList.SearchNode(i); 848 Console.WriteLine(" {0}\t{1}\t{2}", temp.Stu_no, temp.Stu_name, temp.Stu_score); 849 } 850 break; 851 } 852 case '7': 853 { 854 return; 855 } 856 default: 857 break; 858 } 859 Console.WriteLine("按任意键继续...."); 860 Console.ReadLine(); 861 } 862 } 863 } 864 }
注:本文整理自《数据结构(C#语言版)》 清华大学出版社 !!!