introduction these lecture notes cover the key ideas involved in designing algorithms we shall see how they depend on the design of suitable data structuresand how some structures and algorithms are more efficient than others for the same task we will concentrate on few basic taskssuch as storingsorting and searching datathat underlie much of computer sciencebut the techniques discussed will be applicable much more generally we will start by studying some key data structuressuch as arrayslistsqueuesstacks and treesand then move on to explore their use in range of different searching and sorting algorithms this leads on to the consideration of approaches for more efficient storage of data in hash tables finallywe will look at graph based representations and cover the kinds of algorithms needed to work efficiently with them throughoutwe will investigate the computational efficiency of the algorithms we developand gain intuitions about the pros and cons of the various potential approaches for each task we will not restrict ourselves to implementing the various data structures and algorithms in particular computer programming languages ( javac ocaml )but specify them in simple pseudocode that can easily be implemented in any appropriate language algorithms as opposed to programs an algorithm for particular task can be defined as " finite sequence of instructionseach of which has clear meaning and can be performed with finite amount of effort in finite length of timeas suchan algorithm must be precise enough to be understood by human beings howeverin order to be executed by computerwe will generally need program that is written in rigorous formal languageand since computers are quite inflexible compared to the human mindprograms usually need to contain more details than algorithms here we shall ignore most of those programming details and concentrate on the design of algorithms rather than programs the task of implementing the discussed algorithms as computer programs is importantof coursebut these notes will concentrate on the theoretical aspects and leave the practical programming aspects to be studied elsewhere having said thatwe will often find it useful to write down segments of actual programs in order to clarify and test certain theoretical aspects of algorithms and their data structures it is also worth bearing in mind the distinction between different programming paradigmsimperative programming describes computation in terms of instructions that change the program/data statewhereas declarative programming