Thứ Bảy, 17 tháng 9, 2011

CTDL: Tìm Kiếm


Bài toán 1. Tìm kiếm và mô phỏng tiến trình thực hiện thuật toán tìm kiếm tuyến tính và tìm kiếm nhị phân.
Yêu cầu: 
               + Tạo mảng A gồm các số tự động phát sinh trong một giới hạn mà bạn chọn.
               + Xuất mảng A để biết tình trạng dữ liệu hiện tại.
               + Thực hiện quá trình tìm kiếm giá trị X và cho ra kết quả.
Bài toán 2. Tiến hành ứng dụng thuật toán tìm kiếm vào dữ liệu có cấu trúc
Yêu cầu:
               + Xây dựng cấu trúc sinh viên với các thông tin: MSSV, HoTen, Diem
               + Các hàm thao tác trên danh sách sinh viên như : nhập, xuất
               + Tìm kiếm một sinh viên có MSSV là 0394876 và in ra các thông tin chi tiết của sinh viên đó
Thông tin về hàm trong C:
void gotoxy(int x, int y);       Hàm gotoxy có nghĩa là dời con trỏ về tọa độ thứ x,y nào đó trên màn hình.
void delay(long milisec);        Hàm delay là ngừng chương trình trong 1/1000 giây.
Cả hai hàm này nằm trong thư viện conio.h nhưng trong Visual C++ thì chỉ có thể dùng hàm Sleep để thế cho delay còn gotoxy thì có thể điều chỉnh lại bằng cách sử dụng đoạn code dưới đây.
Hàm gotoxy tạm thời có thể tự định nghĩa như sau:

Code:

#include "windows.h"
void gotoxy(int x,int y)
{ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE) ;
COORD position = {x,y} ; SetConsoleCursorPosition(hStdout,position ) ;
}
Định nghĩa xong thì dùng y như là gotoxy của thư viện conio.h.
Một số source code tham khảo:
Thuật toán tìm kiếm nhị phân tìm phần tử x trong mảng a.
int binarysearch(int a[], int x)  // x là giá trị cần tìm trong mảng a
{
    int left , right , mid;
    left = 0;
    right = n-1;  // n là số phần tử mảng a
    while (left <= right)
    {          mid = (left + right) / 2;
        if (a[mid] < x)
            left = mid +1;
        else
        {    if (a[mid] > x)
                right = mid - 1;
            else
                return mid;
        }
    }
    return -1;
}

Hàm khởi tạo mảng A với N phần tử.
void initArray(int* A, int N)
{
      for (int i=0; i<N; i++)
            A[i] = rand() % 100;
}

Hàm in tạo mảng A với N phần tử ra màn hình tại tọa độ (XY, YY).
void printArray(int* A, int N)
{
      textcolor(3);
      gotoxy(XX-5, YY);
      cprintf("A = [");
      for (int i=0; i<N; i++)
      {
            gotoxy(XX + i* 4, YY);
            cprintf("%3d ", A[i]);
      }
      cprintf("]");
      gotoxy(1, YY);
}


CODE chương trình minh họa thuật toán tìm kiếm tuyến tính
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <mem.h>
#include <dos.h>
#include <graphics.h>

int XX = 10, YY = 10;

void initArray(int* A, int N)
{
      for (int i=0; i<N; i++)
            A[i] = rand() % 100;
}

void printArray(int* A, int N)
{
      textcolor(3);
      gotoxy(XX-5, YY);
      cprintf("A = [");
      for (int i=0; i<N; i++)
      {
            gotoxy(XX + i* 4, YY);
            cprintf("%3d ", A[i]);
      }
      cprintf("]");
      gotoxy(1, YY);
}

void printLineSearch(int* A, int N, int X)
{
      for (int i=0; i<N; i++)
      {
            for (int j=0; j<4; j++)
            {
                  delay(100);
                  textcolor(2);
                  gotoxy(XX+(i-1)*4+j, YY+2);
                  cprintf(" %3d ?", X);
            }

            if (A[i] == X)
            {
                  textcolor(4 + BLINK);
                  gotoxy(XX+(i-1)*4+j, YY);
                  cprintf("%3d ", A[i]);
                  gotoxy(XX, YY + 4);
                  cprintf("ANS: Found");
                  gotoxy(XX-3, YY);
                  return;
            }
            else
            {
                  textcolor(4 + BLINK);
                  gotoxy(XX+(i-1)*4+j, YY);
                  cprintf("%3d ", A[i]);
            }

            gotoxy(XX-3, YY);
            delay(1000);

            textcolor(6);
            gotoxy(XX+(i-1)*4+j, YY);
            cprintf("%3d ", A[i]);
      }

      textcolor(4 + BLINK);
      gotoxy(XX-4, YY + 4);
      cprintf("ANS: Not Found");
      gotoxy(XX-3, YY);
}

void sort(int* A, int N)
{
      for (int i=0; i<N-1; i++)
      {
            for (int j=i+1; j<N; j++)
            {
                  if (A[i]>A[j])
                  {
                        int t = A[i];
                        A[i] = A[j];
                        A[j] = t;
                  }
            }
      }

}
void printBinarySearch(int* A, int N, int X)
{
      int l = 0;
      int r = N-1;
      while (l<=r)
      {
            int m = (l+r) / 2;
            if (A[m] < X)
                  l = m;
            if (A[m] > X)
                  r = m;
            if (A[m] == X)
            {
                  textcolor(4 + BLINK);
                  gotoxy(XX+(m-1)*4+4, YY);
                  cprintf("%3d ", A[m]);
                  gotoxy(XX, YY + 4);
                  cprintf("ANS: Found");
                  gotoxy(XX-3, YY);
                  return;
            }
      }
}

void main()
{
      int A[100], N =15;

      clrscr();

      initArray(A, N);
      printArray(A, N);

      printLineSearch(A, N, A[11]);

      sort(A, N);
      printBinarySearch(A, N, A[10]);

      getch();
}
Read More...

Danh sách liên kết đơn


Các thao tác trên danh sách liên kết đơn(single-link list)
1.Định nghĩa tổng quát
Code:
struct tq { thtin_t phantu; struc tq*tiep; }; typedef struct tq tq_t;
2.Con trỏ tới 1 node
Code:
struct node { int infor; struct node *next; }; typedef struct node *NODEPTR;
3.Cấp phát bộ nhớ cho 1 node
Code:
NODEPTR Getnode(void) { NODEPTR p; P = (NODEPTR) malloc(sizeof( struct node)); Return(p); }
4.Giải phóng 1 node
NODEPTR Freenode( NODEPTR p){ free(p); }
5.Thêm phần tử vào đỉnh danh sách
void Push_Top( NODEPTR *plist, int x) { NODEPTR p; p= Getnode(); p -> infor = x; p ->next = *plist; *plist = p; }
6.Thêm node mới vào cuối danh sách
void Push_Bottom( NODEPTR *plist, int x) {
	NODEPTR p, q;
	p= Getnode(); //
	p->infor = x;
	q = *plist;
	while (q-> next != NULL)
		q = q -> next;

	q -> next = p;
	p ->next = NULL;
}
7.Thêm node mới vào giữa danh sách
void Push_Before( NODEPTR p, int x ){ NODEPTR q; if (p->next==NULL) Push_Bottom(p, x); else { q= Getnode(); q -> infor = x; q-> next = p-> next; p->next = q; } }
8. Xóa 1 node đầu danh sách
void Del_Top( NODEPTR *plist) { NODEPTR p; p = *plist; if (p==NULL) return; (*plist) = (*plist) -> next; p-> next = NULL; Freenode(p); }
9.Xóa node cuối danh sách
void Del_Bottom(NODEPTR *plist) { NODEPTR p, q; if (*plist==NULL) return; else if ( (*plist)->next==NULL)) Del_Top(plist); else { p = *plist; while (p->next!=NULL){ q = p; p = p->next; } // p lµ node cuèi danh s¸ch; q->next =NULL; Freenode(p); } }
10.Xóa node giữa danh sách
void Del_before(NODEPTR p){ NODEPTR q; if (p->next==NULL) return; q = p ->next; p->next = q->next; Freenode(q); }
Ngoài ra các thao tác duyệt danh sách, tìm kiếm trên danh sách…
Chúng ta xét 1 ứng dụng đơn giản của danh sách liên kết đơn sau;
Chương trình quản lí sinh viên với dạng đơn giản chỉ gồm mã SV và họ tên
#include    <stdio.h>
#include    <stdlib.h>
#include    <conio.h>
#include    <dos.h>
#include    <string.h>
#include     <math.h>
#include <alloc.h>
#define TRUE 1
#define FALSE 0

typedef struct {
    int masv;
    char hoten[20];
} sinhvien;
typedef struct node{
    sinhvien infor;
    struct node *next;
} *NODEPTR;
void Initialize(NODEPTR *plist){
    *plist=NULL;
}
NODEPTR Getnode(void){
    NODEPTR p;
    p=(NODEPTR) malloc(sizeof(struct node));
    return(p);
}
void Freenode(NODEPTR p){
    free(p);
}
int Emptynode(NODEPTR *plist){
    if(*plist==NULL)
        return(TRUE);
    return(FALSE);
}
NODEPTR Inserttop(NODEPTR *plist, sinhvien x){
    NODEPTR p;
    p=Getnode();
    p->infor=x;
    if(Emptynode(plist)){
        p->next=NULL;
        *plist=p;
        return(p);
    }
    p->next=*plist;
    *plist=p;
    return(p);
}
int Bottomnode(NODEPTR *plist){
    int i; NODEPTR p;
    if(Emptynode(plist))
        return(-1);
    p=*plist;i=0;
    while(p!=NULL){
        i=i+1;
        p=p->next;
    }
    return(i);
}
NODEPTR Insertbottom(NODEPTR *plist, sinhvien x){
    NODEPTR p, q;int n,i;
    n=Bottomnode(plist);
    if(n==-1){
        Inserttop(plist,x);
        return(*plist);
    }
    p=*plist;i=0;q=Getnode();q->infor=x;
    while(i<n-1){
        p=p->next;
        i=i+1;
    }
    p->next=q;q->next=NULL;
    delay(2000);return(q);
}
NODEPTR Insertafter(NODEPTR *plist, sinhvien x, int n){
    NODEPTR p,q; int i;
    if(n<0){
        printf("\n Vi tri khong hop le");
        delay(2000);return(NULL);
    }
       p=*plist;i=0;
    while(p!=NULL && i<n){
        i=i+1;
        p=p->next;
    }
    if(p==NULL){
        printf("\n Vi tri khong hop le");
        delay(2000); return(NULL);
    }
    q=Getnode();q->infor=x;
    q->next= p->next;
    p->next=q;
    return(q);
}
void Deltop(NODEPTR *plist){
    NODEPTR p, q;
    p=*plist;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000); return;
    }
    q=p;p=p->next;*plist=p;
    printf("\n Node bi loai bo");
    printf("\n%-5d%-20s",q->infor.masv, q->infor.hoten);
    delay(2000);Freenode(q);
}
void Delbottom(NODEPTR *plist){
    NODEPTR p,q; int i,n;
    n=Bottomnode(plist);
    if(n==-1){
        printf("\n Danh sach rong");
        delay(2000); return;
    }
    if(n==1){
        Deltop(plist);return;
    }
    p=*plist;i=0;
    while(i<n-2){
        p=p->next;
        i=i+1;
    }
    q=p->next;p->next=NULL;
    printf("\n Node duoc loai bo");
    printf("\n %-5d%-20s",q->infor.masv,q->infor.hoten);
    delay(2000); Freenode(q);
}
void Delcurrent(NODEPTR *plist, int n){
    NODEPTR p,q; int i;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000);return;
    }
    if(n==0){
        Deltop(plist); return;
    }
    p=*plist; i=0;
    while(p!=NULL && i<n-1){
        i=i+1;
        p=p->next;
    }
    if(p->next==NULL){
        printf("\n Node khong hop le");
        delay(2000); return;
    }
    q=p->next;p->next=q->next;
    printf("\n Node duoc loai bo");
    printf("\n %-5d%-20s",q->infor.masv, q->infor.hoten);
    delay(2000); Freenode(q);
}
void Travenode(NODEPTR *plist){
    NODEPTR p;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000);return;
    }
    p=*plist;
    while(p!=NULL){
        printf("\n %-5d%-20s",p->infor.masv, p->infor.hoten);
        p=p->next;
    }
    delay(2000);
}
void Sortnode(NODEPTR *plist){
    NODEPTR p,q;sinhvien temp;
    for(p=*plist; p!=NULL; p=p->next){
        for(q=p->next; q!=NULL; q=q->next){
            if(p->infor.masv>q->infor.masv){
                temp=p->infor; p->infor=q->infor;
                q->infor=temp;
            }
        }
    }
    printf("\n Danh sach duoc sap xep");
    for(p=*plist; p!=NULL; p=p->next){
        printf("\n %-5d%-20s",p->infor.masv,p->infor.hoten);
    }
    delay(2000);
}
void Searchnode(NODEPTR *plist, int masv){
    NODEPTR p;
    p=*plist;
    while(p!=NULL && p->infor.masv!=masv)
        p=p->next;
    if(p==NULL)
        printf("\n Node khong ton tai");
    else {
        printf("\n Node can tim");
        printf("\n %-5d%-20s",p->infor.masv,p->infor.hoten);
    }
    delay(2000);
}

void Thuchien(void){
    NODEPTR plist; sinhvien x,y;int vitri; char c;
    Initialize(&plist);
    do {
        clrscr();
        printf("\n THAO TAC VOI SINGLE LINK LIST");
        printf("\n 1- Them node dau danh sach");
        printf("\n 2- Them node cuoi danh sach");
        printf("\n 3- Them node giua danh sach");
        printf("\n 4- Loai bo node dau danh sach");
        printf("\n 5- Loai bo node cuoi danh sach");
        printf("\n 6- Loai node giua danh sach");
        printf("\n 7- Duyet danh sach");
        printf("\n 8- Sap xep danh sach");
        printf("\n 9- Tim kiem danh sach");
        printf("\n 0- Tro ve");
        c=getch();
        switch(c){
            case '1':
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Inserttop(&plist,x); break;
            case '2':
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Insertbottom(&plist,x); break;
            case '3':
                printf("\n Vi tri tren:"); scanf("%d",&vitri);
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Insertafter(&plist,x,vitri-1); break;
            case '4': Deltop(&plist);break;
            case '5': Delbottom(&plist);break;
            case '6':
                fflush(stdin);printf("\n Vi tri loai bo:");
                scanf("%d",&vitri);
                Delcurrent(&plist,vitri-1);break;
            case '7': Travenode(&plist); break;
            case '8': Sortnode(&plist);break;
            case '9':
                fflush(stdin);printf("\n Ma sinh vien:");
                scanf("%d",&vitri);
                Searchnode(&plist, vitri);break;
        }
    } while(c!='0');
}
void main(void){
    Thuchien();
}


#include    <stdio.h>
#include    <stdlib.h>
#include    <conio.h>
#include    <dos.h>
#include    <string.h>
#include     <math.h>
#include <alloc.h>
#define TRUE 1
#define FALSE 0
typedef struct {
    int masv;
    char hoten[20];
} sinhvien;
typedef struct node{
    sinhvien infor;
    struct node *next;
} *NODEPTR;
void Initialize(NODEPTR *plist){
    *plist=NULL;
}
NODEPTR Getnode(void){
    NODEPTR p;
    p=(NODEPTR) malloc(sizeof(struct node));
    return(p);
}
void Freenode(NODEPTR p){
    free(p);
}
int Emptynode(NODEPTR *plist){
    if(*plist==NULL)
        return(TRUE);
    return(FALSE);
}
NODEPTR Inserttop(NODEPTR *plist, sinhvien x){
    NODEPTR p;
    p=Getnode();
    p->infor=x;
    if(Emptynode(plist)){
        p->next=NULL;
        *plist=p;
        return(p);
    }
    p->next=*plist;
    *plist=p;
    return(p);
}
int Bottomnode(NODEPTR *plist){
    int i; NODEPTR p;
    if(Emptynode(plist))
        return(-1);
    p=*plist;i=0;
    while(p!=NULL){
        i=i+1;
        p=p->next;
    }
    return(i);
}
NODEPTR Insertbottom(NODEPTR *plist, sinhvien x){
    NODEPTR p, q;int n,i;
    n=Bottomnode(plist);
    if(n==-1){
        Inserttop(plist,x);
        return(*plist);
    }
    p=*plist;i=0;q=Getnode();q->infor=x;
    while(i<n-1){
        p=p->next;
        i=i+1;
    }
    p->next=q;q->next=NULL;
    delay(2000);return(q);
}
NODEPTR Insertafter(NODEPTR *plist, sinhvien x, int n){
    NODEPTR p,q; int i;
    if(n<0){
        printf("\n Vi tri khong hop le");
        delay(2000);return(NULL);
    }
       p=*plist;i=0;
    while(p!=NULL && i<n){
        i=i+1;
        p=p->next;
    }
    if(p==NULL){
        printf("\n Vi tri khong hop le");
        delay(2000); return(NULL);
    }
    q=Getnode();q->infor=x;
    q->next= p->next;
    p->next=q;
    return(q);
}
void Deltop(NODEPTR *plist){
    NODEPTR p, q;
    p=*plist;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000); return;
    }
    q=p;p=p->next;*plist=p;
    printf("\n Node bi loai bo");
    printf("\n%-5d%-20s",q->infor.masv, q->infor.hoten);
    delay(2000);Freenode(q);
}
void Delbottom(NODEPTR *plist){
    NODEPTR p,q; int i,n;
    n=Bottomnode(plist);
    if(n==-1){
        printf("\n Danh sach rong");
        delay(2000); return;
    }
    if(n==1){
        Deltop(plist);return;
    }
    p=*plist;i=0;
    while(i<n-2){
        p=p->next;
        i=i+1;
    }
    q=p->next;p->next=NULL;
    printf("\n Node duoc loai bo");
    printf("\n %-5d%-20s",q->infor.masv,q->infor.hoten);
    delay(2000); Freenode(q);
}
void Delcurrent(NODEPTR *plist, int n){
    NODEPTR p,q; int i;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000);return;
    }
    if(n==0){
        Deltop(plist); return;
    }
    p=*plist; i=0;
    while(p!=NULL && i<n-1){
        i=i+1;
        p=p->next;
    }
    if(p->next==NULL){
        printf("\n Node khong hop le");
        delay(2000); return;
    }
    q=p->next;p->next=q->next;
    printf("\n Node duoc loai bo");
    printf("\n %-5d%-20s",q->infor.masv, q->infor.hoten);
    delay(2000); Freenode(q);
}
void Travenode(NODEPTR *plist){
    NODEPTR p;
    if(Emptynode(plist)){
        printf("\n Danh sach rong");
        delay(2000);return;
    }
    p=*plist;
    while(p!=NULL){
        printf("\n %-5d%-20s",p->infor.masv, p->infor.hoten);
        p=p->next;
    }
    delay(2000);
}
void Sortnode(NODEPTR *plist){
    NODEPTR p,q;sinhvien temp;
    for(p=*plist; p!=NULL; p=p->next){
        for(q=p->next; q!=NULL; q=q->next){
            if(p->infor.masv>q->infor.masv){
                temp=p->infor; p->infor=q->infor;
                q->infor=temp;
            }
        }
    }
    printf("\n Danh sach duoc sap xep");
    for(p=*plist; p!=NULL; p=p->next){
        printf("\n %-5d%-20s",p->infor.masv,p->infor.hoten);
    }
    delay(2000);
}
void Searchnode(NODEPTR *plist, int masv){
    NODEPTR p;
    p=*plist;
    while(p!=NULL && p->infor.masv!=masv)
        p=p->next;
    if(p==NULL)
        printf("\n Node khong ton tai");
    else {
        printf("\n Node can tim");
        printf("\n %-5d%-20s",p->infor.masv,p->infor.hoten);
    }
    delay(2000);
}

void Thuchien(void){
    NODEPTR plist; sinhvien x,y;int vitri; char c;
    Initialize(&plist);
    do {
        clrscr();
        printf("\n THAO TAC VOI SINGLE LINK LIST");
        printf("\n 1- Them node dau danh sach");
        printf("\n 2- Them node cuoi danh sach");
        printf("\n 3- Them node giua danh sach");
        printf("\n 4- Loai bo node dau danh sach");
        printf("\n 5- Loai bo node cuoi danh sach");
        printf("\n 6- Loai node giua danh sach");
        printf("\n 7- Duyet danh sach");
        printf("\n 8- Sap xep danh sach");
        printf("\n 9- Tim kiem danh sach");
        printf("\n 0- Tro ve");
        c=getch();
        switch(c){
            case '1':
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Inserttop(&plist,x); break;
            case '2':
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Insertbottom(&plist,x); break;
            case '3':
                printf("\n Vi tri tren:"); scanf("%d",&vitri);
                printf("\n Ma sinh vien:");scanf("%d", &x.masv);
                fflush(stdin); printf("\n Ho va ten:");gets(x.hoten);
                Insertafter(&plist,x,vitri-1); break;
            case '4': Deltop(&plist);break;
            case '5': Delbottom(&plist);break;
            case '6':
                fflush(stdin);printf("\n Vi tri loai bo:");
                scanf("%d",&vitri);
                Delcurrent(&plist,vitri-1);break;
            case '7': Travenode(&plist); break;
            case '8': Sortnode(&plist);break;
            case '9':
                fflush(stdin);printf("\n Ma sinh vien:");
                scanf("%d",&vitri);
                Searchnode(&plist, vitri);break;
        }
    } while(c!='0');
}
void main(void){
    Thuchien();
}

Read More...

18 bài toán về danh sách liên kết


Danh sách liên kết là một khái niệm rất cơ bản trong Lập trình. Việc tìm hiểu về danh sách liên kết trong C/C++ có nhiều điểm thú vị là vì:
  • Cấu trúc của danh sách liên kết rất đơn giản, việc mô tả nó rất dễ dàng
  • Tuy vậy các giải thuật xử lý danh sách liên kết lại có thể rất phức tạp và thú vị
  • Làm việc với danh sách liên kết đòi hỏi việc sử dụng con trỏ một cách thành thạo
  • Các danh sách liên kết đặc biệt phù hợp cho việc mô tả dùng hình vẽ. Làm việc với chúng giúp bạn phát triển kỹ năng hình tượng hóa vấn đề khi lập trình
Bài viết này sẽ điểm qua một số khái niệm cơ bản về danh sách liên kết và đưa ra 18 bài toán về danh sách liên kết theo thứ tự từ dễ đến khó.

Cơ bản về danh sách liên kết

Cấu trúc của một danh sách liên kết đơn như sau:
struct node {
 int data;
 struct node* next;
};
Chúng ta sẽ điểm qua một vài hàm cơ bản dùng để làm việc với danh sách. Hàm tính độ dài của danh sách như sau:
int Length(struct node *head) {
        int count =0;
        struct node *elem = head;
        while (elem) {
                count ++;
                elem = elem->next;
        }
        return count;
}
Hàm thêm một phần tử vào đầu danh sách:
void Push(struct node** headRef, int data) {
 struct node* newNode = malloc(sizeof(struct node));
 newNode->data = data;
 newNode->next = *headRef; // The '*' to dereferences back to the real head
 *headRef = newNode; // ditto
}
Chúng ta có thể dùng hàm sau để xây dựng một danh sách kết nối đơn giản, dùng làm đầu vào cho các bài toán ở phần sau:
struct node *BuildOneTwoThree() {
        struct node *head = NULL;
        struct node *second = NULL ;
        struct node *third = NULL;

        head = (struct node*) malloc(sizeof (struct node));
        second = (struct node*) malloc(sizeof (struct node));
        third = (struct node*) malloc(sizeof (struct node));

        if (!head || !second || !third) {
                printf("cannot allocate memory\n");
                exit(1);
        }
        head->data=1;
        head->next=second;

        second->data=2;
        second->next=third;

        third->data=3;
        third->next=NULL;

        return head;
}

18 bài toán về danh sách liên kết

1.  Count()

Viết hàm Count() thực hiện việc đếm các lần xuất hiện của một số nguyên trong một danh sách. 
void CountTest() {
 List myList = BuildOneTwoThree(); // build {1, 2, 3}
 int count = Count(myList, 2); // returns 1 since there's 1 '2' in the list
}
Mẫu hàm:
/* Given a list and an int, return the number of times that int occurs in the list. */
int Count(struct node* head, int searchFor) {
 // Your code
}

2. Nth()

Viết hàm Nth() trả về đối tượng thứ n trong danh sách (bắt đầu từ 0)
void GetNthTest() {
 struct node* myList = BuildOneTwoThree(); // build {1, 2, 3}
 int lastNode = GetNth(myList, 2); // returns the value 3 
}
Mẫu hàm:
// Given a list and an index, return the data
// in the nth node of the list. The nodes are numbered from 0.
// Assert fails if the index is invalid (outside 0..lengh-1).
int GetNth(struct node* head, int index) {
 // Your code
}

3. DeleteList()

Viết hàm DeleteList() để xóa một danh sách liên kết và thiết lập con trỏ head thành NULL
void DeleteListTest() {
 struct node* myList = BuildOneTwoThree(); // build {1, 2, 3}
 DeleteList(&myList); // deletes the three nodes and sets myList to NULL
}
Mẫu hàm:
void DeleteList(struct node** head) {
 // Your code
}

4. Pop()

Viết hàm Pop() để lấy ra phần tử đầu tiên của danh sách, phần từ này đồng thời được xóa khỏi danh sách.
void PopTest() {
 struct node* head = BuildOneTwoThree(); // build {1, 2, 3}
 int a = Pop(&head); // deletes "1" node and returns 1
 int b = Pop(&head); // deletes "2" node and returns 2
 int c = Pop(&head); // deletes "3" node and returns 3
 int len = Length(head); // the list is now empty, so len == 0
}
Mẫu hàm:
/*
The opposite of Push(). Takes a non-empty list
and removes the front node, and returns the data
which was in that node.
*/
int Pop(struct node** headRef) {
 // your code...
}

5. InsertNth()

Viết hàm để thêm vào danh sách một đối tượng tại vị trí thứ n
void InsertNthTest() {
 struct node* head = NULL; // start with the empty list
 InsertNth(&head, 0, 13); // build {13)
 InsertNth(&head, 1, 42); // build {13, 42}
 InsertNth(&head, 1, 5); // build {13, 5, 42}
 DeleteList(&head); // clean up after ourselves
}
Mẫu hàm:
/*
A more general version of Push().
Given a list, an index 'n' in the range 0..length,
and a data element, add a new node to the list so
that it has the given index.
*/
void InsertNth(struct node** headRef, int index, int data) {
 // your code...
}

6. SortedInsert()

Có một danh sách đã được sắp xếp. Viết hàm để thêm vào danh sách một đối tượng vào danh sách và giữ được thứ tự sắp xếp.
Mẫu hàm:
void SortedInsertNth(struct node** headRef,struct node *newNode) {
 // your code
}

7. InsertSort()

Nhận một danh sách đầu vào, sắp xếp danh sách này theo thứ tự tăng dần, bài toán yêu cầu sử dụng hàm SortedInsert() ở câu 6.
Mẫu hàm:
// Given a list, change it to be in sorted order (using SortedInsert()).
void InsertSort(struct node** headRef) { // Your code
}

8. Append()

Viết hàm nhận hai tham số là danh sách A và B, trả về danh sách A với B được gắn vào đuôi của A và B được thiết lập là NULL.
Mẫu hàm:
// Append 'b' onto the end of 'a', and then set 'b' to NULL.
void Append(struct node** aRef, struct node** bRef) {
 // Your code...
}

9. FronBackSplit()

Viết hàm tách một danh sách liên kết ra làm hai, ngắt ở giữa. Nếu chiều dài của danh sách là lẻ thì danh sách thứ nhất sẽ dài hơn danh sách thứ hai một phần tử.
Mẫu hàm:
/*
Split the nodes of the given list into front and back halves,
and return the two lists using the reference parameters.
If the length is odd, the extra node should go in the front list.
*/
void FrontBackSplit(struct node* source,
struct node** frontRef, struct node** backRef) {
 // Your code...
}

10. RemoveDuplicates()

Cho một danh sách đã được sắp xếp theo thứ tự tăng dần, hãy xóa các phần tử bị lặp với điều kiện danh sách chỉ được duyệt một lần.
Mẫu hàm:
/*
Remove duplicates from a sorted list.
*/
void RemoveDuplicates(struct node* head) {
 // Your code...
}

11. MoveNode()

Mẫu hàm:
/*
Take the node from the front of the source, and move it to
the front of the dest.
It is an error to call this with the source list empty.
*/
void MoveNode(struct node** destRef, struct node** sourceRef) {
 // Your code
}

12. ShuffleMerge()

Mẫu hàm:
/*
Merge the nodes of the two lists into a single list taking a node
alternately from each list, and return the new list.
*/
struct node* ShuffleMerge(struct node* a, struct node* b) {
 // Your code
}




Lời giải

1. Count()

int Count(struct node* head, int searchFor) {
 int count =0;
 struct node *element = head;
 while (element) {
  if ( element->data == searchFor) count++;
  element = element-> next;
 }
 return count;
}

2. Nth()

int GetNth(struct node* head, int index) {
        struct node *elem = head;
        int i = 0;

        while (elem) {
                if (i==index)
                        return elem->data;
                elem = elem->next;
                i++;
        }
        assert(0);
}

3. DeleteList()

void DeleteList(struct node **head) {
        struct node *elem = *head;
        struct node *another;
        while (elem) {
                another = elem->next;
                free(elem);
                elem = another;
        }
 *head = NULL;
}

4. Pop()

int Pop(struct node **head) {
        struct node *elem = *head;
        int a;
        assert( elem );
        a = elem->data;
        *head = elem->next;
        free(elem);
        return a;
}

5. InsertNth()

void InsertNth(struct node** head, int index, int data) {
        struct node *newElem;
        newElem = (struct node*) malloc(sizeof(struct node));
        newElem->data = data;
        int i = 0;
        struct node *elem = *head;
        while (elem) {
                if (i== (index-1)) {
                        newElem->next = elem->next;
                        elem->next = newElem;
                        break;
                }
                i++;
                elem = elem->next;
 }
}

6. SortedInsert()

void InsertNth(struct node** head, truct node *newNode) {
        struct node *elem = *head;
        while (elem) {
                if (newNode->data < elem->data) {
                        newNode->next = elem->next;
                        elem->next = newNode;
                        break;
                }
                elem = elem->next;
 }
}

7. InsertSort()

void InsertNth(struct node** head, truct node *newNode) {
}

8. Append()

void Append(struct node** aRef, struct node** bRef) {
 struct node *elem = *aRef;
 if (*aRef == NULL) {
  *aRef = *bRef;
 } else {
  while (elem->next) {
   elem = elem->next;
  }
  elem->next = *bRef;
 }
 *bRef = NULL;
}

9. FronBackSplit()


void FrontBackSplit(struct node* source, 
 struct node** frontRef, struct node** backRef) {
 if (source == NULL || source->next == NULL) {
  *frontRef = source;
  *backRef = NULL;
 } else {
  struct node *fast = source;
  struct node *slow = source->next;
  while (fast) {
   fast = fast->next;
   if (fast != NULL) {
    fast = fast->next;
    slow = slow->next;
   }
  }
  *frontRef = source;
  *backRef = slow->next;
  slow->next = NULL;
 }
}


....
Read More...